@hitch42/applet 0.1.1-beta.1 → 0.1.1-beta.11

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 (178) 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 +53 -29
  7. package/dist/build-Bh_S5BUv.js +2 -0
  8. package/dist/{build-Rk3xDZV7.js → build-CEfFoIZZ.js} +30 -14
  9. package/dist/ci-BKw14X2h.js +69 -0
  10. package/dist/client.d.ts +3 -3
  11. package/dist/{contract-DMrpbaLJ.d.ts → contract-CsUpTBe0.d.ts} +1 -1
  12. package/dist/{deploy-D3BGDqgC.js → deploy-wGYjwXrx.js} +249 -35
  13. package/dist/email-DBTVhNB_.js +62 -0
  14. package/dist/{generate-CH0VQmUi.js → generate-BEIYs17x.js} +79 -25
  15. package/dist/generate-Dox-OYt6.js +2 -0
  16. package/dist/headers-DkNr9MLJ.js +17 -0
  17. package/dist/index.d.ts +123 -11
  18. package/dist/index.js +142 -26
  19. package/dist/{init-BS1Y-eNL.js → init-6oGPM46R.js} +17 -18
  20. package/dist/load-config-xEdTXs0y.js +27 -0
  21. package/dist/log-context-zu8U9Sjm.js +73 -0
  22. package/dist/login-CUx3TmFQ.js +12 -0
  23. package/dist/{logs-m00pzr_O.js → logs-DSjuEN0Q.js} +20 -22
  24. package/dist/{manifest-BQCAxATS.d.ts → manifest-C6_F4bL8.d.ts} +9 -0
  25. package/dist/{manifest-DyoJ1MIL.js → manifest-CJSL9GuC.js} +25 -3
  26. package/dist/me-BW7Paary.js +32 -0
  27. package/dist/{project-CxN-Dtc7.js → project-BRZGd6xq.js} +227 -34
  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-CP7Ce3Np.js → variables-DT5RyHdH.js} +14 -39
  40. package/dist/vite.d.ts +3 -60
  41. package/dist/vite.js +503 -34
  42. package/dist/workflow-engine-BOTzURKM.js +111 -0
  43. package/dist/{auth-DaVK0k5R.js → workspace-D0dnnlxL.js} +75 -40
  44. package/package.json +19 -6
  45. package/scaffold/.agents/skills/hitch-applets/SKILL.md +60 -15
  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 +29 -2
  49. package/scaffold/.agents/skills/hitch-applets/references/markdown.md +2 -0
  50. package/scaffold/.agents/skills/hitch-applets/references/performance.md +74 -0
  51. package/scaffold/.agents/skills/hitch-applets/references/records.md +32 -8
  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 +129 -0
  56. package/scaffold/.agents/skills/hitch-data/SKILL.md +52 -0
  57. package/scaffold/.agents/skills/hitch-data/references/attributes.md +127 -0
  58. package/scaffold/.agents/skills/hitch-data/references/limits.md +64 -0
  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 +15 -0
  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-CEku1lyb.js +0 -2
  177. package/dist/generate-6Nbt7uii.js +0 -2
  178. package/dist/load-config-BnxocLAQ.js +0 -56
@@ -0,0 +1,150 @@
1
+ ---
2
+ name: compositions/broadcast-realtime-and-multi-tab-synchronization
3
+ description: >
4
+ Use this when synchronizing TanStack Query caches with broadcastQueryClient,
5
+ BroadcastChannel, multi-tab cache sync, realtime invalidation, WebSocket
6
+ events, server/browser boundaries, and experimental broadcast behavior.
7
+ type: composition
8
+ library: TanStack Query
9
+ library_version: "5.101.0"
10
+ requires:
11
+ - lifecycle/setup-query-client-and-providers
12
+ - core/write-mutations-and-invalidate-related-queries
13
+ - compositions/persist-offline-and-restore-caches
14
+ sources:
15
+ - TanStack/query:docs/framework/react/plugins/broadcastQueryClient.md
16
+ - TanStack/query:docs/framework/react/guides/query-invalidation.md
17
+ - TanStack/query:examples/react/chat/package.json
18
+ ---
19
+
20
+ ## Setup
21
+
22
+ ```ts
23
+ import { QueryClient } from "@tanstack/react-query";
24
+ import { broadcastQueryClient } from "@tanstack/query-broadcast-client-experimental";
25
+
26
+ export const queryClient = new QueryClient();
27
+
28
+ if (typeof window !== "undefined") {
29
+ broadcastQueryClient({ queryClient, broadcastChannel: "app-query-cache" });
30
+ }
31
+ ```
32
+
33
+ ## Core Integration Patterns
34
+
35
+ ### Invalidate from realtime events
36
+
37
+ ```ts
38
+ import { QueryClient } from "@tanstack/react-query";
39
+
40
+ const queryClient = new QueryClient();
41
+
42
+ export function onTodoChanged(todoId: number) {
43
+ return queryClient.invalidateQueries({ queryKey: ["todo", todoId] });
44
+ }
45
+ ```
46
+
47
+ ### Update narrow cache slices
48
+
49
+ ```ts
50
+ import { QueryClient } from "@tanstack/react-query";
51
+
52
+ const queryClient = new QueryClient();
53
+
54
+ export function onTodoTitle(todo: { id: number; title: string }) {
55
+ queryClient.setQueryData(["todo", todo.id], todo);
56
+ }
57
+ ```
58
+
59
+ ### Keep broadcast client-side
60
+
61
+ ```ts
62
+ import { QueryClient } from "@tanstack/react-query";
63
+ import { broadcastQueryClient } from "@tanstack/query-broadcast-client-experimental";
64
+
65
+ export function installBroadcast(queryClient: QueryClient) {
66
+ if (typeof window === "undefined") return;
67
+ broadcastQueryClient({ queryClient, broadcastChannel: "query-cache" });
68
+ }
69
+ ```
70
+
71
+ ## Common Mistakes
72
+
73
+ ### MEDIUM Unlocked experimental broadcast
74
+
75
+ Wrong:
76
+
77
+ ```ts
78
+ import { QueryClient } from "@tanstack/react-query";
79
+ import { broadcastQueryClient } from "@tanstack/query-broadcast-client-experimental";
80
+
81
+ broadcastQueryClient({ queryClient: new QueryClient() });
82
+ ```
83
+
84
+ Correct:
85
+
86
+ ```ts
87
+ import { QueryClient } from "@tanstack/react-query";
88
+ import { broadcastQueryClient } from "@tanstack/query-broadcast-client-experimental";
89
+
90
+ if (typeof window !== "undefined") {
91
+ broadcastQueryClient({
92
+ queryClient: new QueryClient(),
93
+ broadcastChannel: "query-cache-v1",
94
+ });
95
+ }
96
+ ```
97
+
98
+ The broadcast package is experimental and should be deliberately isolated behind browser-only setup.
99
+
100
+ Source: TanStack/query:docs/framework/react/plugins/broadcastQueryClient.md
101
+
102
+ ### MEDIUM Over-normalized realtime writes
103
+
104
+ Wrong:
105
+
106
+ ```ts
107
+ import { QueryClient } from "@tanstack/react-query";
108
+
109
+ const queryClient = new QueryClient();
110
+ queryClient.setQueryData(["todos"], { byId: { 1: { id: 1 } }, allIds: [1] });
111
+ ```
112
+
113
+ Correct:
114
+
115
+ ```ts
116
+ import { QueryClient } from "@tanstack/react-query";
117
+
118
+ const queryClient = new QueryClient();
119
+ queryClient.invalidateQueries({ queryKey: ["todos"] });
120
+ ```
121
+
122
+ Query is not a normalized cache; invalidation is often safer than duplicating server state models.
123
+
124
+ Source: TanStack/query:docs/framework/react/guides/query-invalidation.md
125
+
126
+ ### HIGH Broadcast on server
127
+
128
+ Wrong:
129
+
130
+ ```ts
131
+ import { QueryClient } from "@tanstack/react-query";
132
+ import { broadcastQueryClient } from "@tanstack/query-broadcast-client-experimental";
133
+
134
+ export const queryClient = new QueryClient();
135
+ broadcastQueryClient({ queryClient });
136
+ ```
137
+
138
+ Correct:
139
+
140
+ ```ts
141
+ import { QueryClient } from "@tanstack/react-query";
142
+ import { broadcastQueryClient } from "@tanstack/query-broadcast-client-experimental";
143
+
144
+ export const queryClient = new QueryClient();
145
+ if (typeof window !== "undefined") broadcastQueryClient({ queryClient });
146
+ ```
147
+
148
+ BroadcastChannel is a browser primitive; server setup should not install it.
149
+
150
+ Source: TanStack/query:docs/framework/react/plugins/broadcastQueryClient.md
@@ -0,0 +1,248 @@
1
+ ---
2
+ name: compositions/compose-query-with-tanstack-router-and-start
3
+ description: >
4
+ Use this when combining TanStack Query with TanStack Router or TanStack Start:
5
+ router context QueryClient, createFileRoute loaders, ensureQueryData,
6
+ @tanstack/react-router-ssr-query, setupRouterSsrQueryIntegration, SSR hydration,
7
+ streaming, redirects, and Start server functions.
8
+ type: composition
9
+ library: TanStack Query
10
+ library_version: "5.101.0"
11
+ requires:
12
+ - lifecycle/setup-query-client-and-providers
13
+ - core/design-query-keys-and-options
14
+ - lifecycle/prefetch-and-remove-request-waterfalls
15
+ sources:
16
+ - TanStack/router:https://tanstack.com/router/latest/docs/integrations/query
17
+ - TanStack/router:https://tanstack.com/router/latest/docs/how-to/setup-ssr
18
+ - TanStack/start:https://tanstack.com/start/latest/docs/framework/react/overview
19
+ - TanStack/query:docs/framework/react/guides/prefetching.md
20
+ - TanStack/query:docs/framework/react/guides/ssr.md
21
+ ---
22
+
23
+ ## Setup
24
+
25
+ ```tsx
26
+ import { QueryClient, QueryClientProvider, useSuspenseQuery } from "@tanstack/react-query";
27
+ import { createFileRoute, createRouter, RouterProvider } from "@tanstack/react-router";
28
+ import { routeTree } from "./routeTree.gen";
29
+
30
+ const queryClient = new QueryClient();
31
+
32
+ const postsQuery = {
33
+ queryKey: ["posts"],
34
+ queryFn: async () => [{ id: 1, title: "Router first" }],
35
+ };
36
+
37
+ export const Route = createFileRoute("/posts")({
38
+ loader: ({ context }) => context.queryClient.ensureQueryData(postsQuery),
39
+ component: PostsPage,
40
+ });
41
+
42
+ function PostsPage() {
43
+ const { data } = useSuspenseQuery(postsQuery);
44
+ return <pre>{JSON.stringify(data)}</pre>;
45
+ }
46
+
47
+ const router = createRouter({ routeTree, context: { queryClient } });
48
+
49
+ export function App() {
50
+ return (
51
+ <QueryClientProvider client={queryClient}>
52
+ <RouterProvider router={router} />
53
+ </QueryClientProvider>
54
+ );
55
+ }
56
+ ```
57
+
58
+ ## Core Integration Patterns
59
+
60
+ ### Put QueryClient in router context
61
+
62
+ ```ts
63
+ import { QueryClient } from "@tanstack/react-query";
64
+ import { createRouter } from "@tanstack/react-router";
65
+ import { routeTree } from "./routeTree.gen";
66
+
67
+ const queryClient = new QueryClient();
68
+
69
+ export const router = createRouter({
70
+ routeTree,
71
+ context: { queryClient },
72
+ defaultPreloadStaleTime: 0,
73
+ });
74
+ ```
75
+
76
+ Set `defaultPreloadStaleTime: 0` when Query owns server-state freshness. Router still preloads and runs loaders, but Query is the cache authority.
77
+
78
+ ### Use loader ensureQueryData for route data
79
+
80
+ ```ts
81
+ import { createFileRoute } from "@tanstack/react-router";
82
+
83
+ const todoQuery = (todoId: string) => ({
84
+ queryKey: ["todo", todoId],
85
+ queryFn: async () => ({ id: todoId, title: "Loaded" }),
86
+ });
87
+
88
+ export const Route = createFileRoute("/todos/$todoId")({
89
+ loader: ({ context, params }) => context.queryClient.ensureQueryData(todoQuery(params.todoId)),
90
+ });
91
+ ```
92
+
93
+ Treat loaders as event handlers that prime the Query cache. Components should still call `useQuery` or `useSuspenseQuery` so the route has an active Query observer.
94
+
95
+ ### Prefer Router SSR Query integration for Router SSR
96
+
97
+ ```ts
98
+ import { QueryClient } from "@tanstack/react-query";
99
+ import { createRouter } from "@tanstack/react-router";
100
+ import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query";
101
+ import { routeTree } from "./routeTree.gen";
102
+
103
+ const queryClient = new QueryClient();
104
+ const router = createRouter({ routeTree, context: { queryClient } });
105
+
106
+ setupRouterSsrQueryIntegration({ router, queryClient });
107
+ ```
108
+
109
+ ## Common Mistakes
110
+
111
+ ### CRITICAL Component-only Query creates route waterfall
112
+
113
+ Wrong:
114
+
115
+ ```tsx
116
+ import { createFileRoute } from "@tanstack/react-router";
117
+ import { useSuspenseQuery } from "@tanstack/react-query";
118
+
119
+ export const Route = createFileRoute("/posts")({ component: PostsPage });
120
+ function PostsPage() {
121
+ const { data } = useSuspenseQuery({
122
+ queryKey: ["posts"],
123
+ queryFn: async () => [{ id: 1 }],
124
+ });
125
+ return <pre>{JSON.stringify(data)}</pre>;
126
+ }
127
+ ```
128
+
129
+ Correct:
130
+
131
+ ```tsx
132
+ import { createFileRoute } from "@tanstack/react-router";
133
+ import { useSuspenseQuery } from "@tanstack/react-query";
134
+
135
+ const postsQuery = { queryKey: ["posts"], queryFn: async () => [{ id: 1 }] };
136
+ export const Route = createFileRoute("/posts")({
137
+ loader: ({ context }) => context.queryClient.ensureQueryData(postsQuery),
138
+ component: PostsPage,
139
+ });
140
+ function PostsPage() {
141
+ const { data } = useSuspenseQuery(postsQuery);
142
+ return <pre>{JSON.stringify(data)}</pre>;
143
+ }
144
+ ```
145
+
146
+ The router can load route-critical data before component render.
147
+
148
+ Source: TanStack/router:https://tanstack.com/router/latest/docs/integrations/query
149
+
150
+ ### CRITICAL Hand-rolled Router hydration
151
+
152
+ Wrong:
153
+
154
+ ```tsx
155
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
156
+ import { createRouter, RouterProvider } from "@tanstack/react-router";
157
+ import { routeTree } from "./routeTree.gen";
158
+
159
+ const queryClient = new QueryClient();
160
+ const router = createRouter({ routeTree });
161
+ export function App() {
162
+ return (
163
+ <QueryClientProvider client={queryClient}>
164
+ <RouterProvider router={router} />
165
+ </QueryClientProvider>
166
+ );
167
+ }
168
+ ```
169
+
170
+ Correct:
171
+
172
+ ```ts
173
+ import { QueryClient } from "@tanstack/react-query";
174
+ import { createRouter } from "@tanstack/react-router";
175
+ import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query";
176
+ import { routeTree } from "./routeTree.gen";
177
+
178
+ const queryClient = new QueryClient();
179
+ const router = createRouter({ routeTree, context: { queryClient } });
180
+ setupRouterSsrQueryIntegration({ router, queryClient });
181
+ ```
182
+
183
+ The Router SSR Query integration handles dehydration, hydration, streamed query results, redirects, and provider wrapping.
184
+
185
+ Source: TanStack/router:https://tanstack.com/router/latest/docs/integrations/query
186
+
187
+ ### HIGH Next.js mental model copied into Start
188
+
189
+ Wrong:
190
+
191
+ ```tsx
192
+ export default async function Page() {
193
+ const posts = await Promise.resolve([{ id: 1 }]);
194
+ return <pre>{JSON.stringify(posts)}</pre>;
195
+ }
196
+ ```
197
+
198
+ Correct:
199
+
200
+ ```tsx
201
+ import { createFileRoute } from "@tanstack/react-router";
202
+
203
+ export const Route = createFileRoute("/posts")({
204
+ loader: ({ context }) =>
205
+ context.queryClient.ensureQueryData({
206
+ queryKey: ["posts"],
207
+ queryFn: async () => [{ id: 1 }],
208
+ }),
209
+ component: () => <p>Posts loaded by the route</p>,
210
+ });
211
+ ```
212
+
213
+ Start is powered by TanStack Router; use file routes, loaders, server functions, and Router SSR before Next-specific app/pages APIs.
214
+
215
+ Source: TanStack/start:https://tanstack.com/start/latest/docs/framework/react/overview
216
+
217
+ ### HIGH Reading loader data instead of observing Query
218
+
219
+ Wrong:
220
+
221
+ ```tsx
222
+ import { createFileRoute, useLoaderData } from "@tanstack/react-router";
223
+
224
+ export const Route = createFileRoute("/posts")({
225
+ loader: ({ context }) => context.queryClient.ensureQueryData(postsQuery),
226
+ component: PostsPage,
227
+ });
228
+
229
+ function PostsPage() {
230
+ const posts = useLoaderData({ from: "/posts" });
231
+ return <pre>{JSON.stringify(posts)}</pre>;
232
+ }
233
+ ```
234
+
235
+ Correct:
236
+
237
+ ```tsx
238
+ import { useSuspenseQuery } from "@tanstack/react-query";
239
+
240
+ function PostsPage() {
241
+ const { data } = useSuspenseQuery(postsQuery);
242
+ return <pre>{JSON.stringify(data)}</pre>;
243
+ }
244
+ ```
245
+
246
+ The loader primes the cache. The component still needs an active Query observer for refetch triggers, invalidation, and garbage collection semantics.
247
+
248
+ See also: `lifecycle/ssr-hydration-and-streaming` for framework SSR recipes.
@@ -0,0 +1,167 @@
1
+ ---
2
+ name: compositions/enforce-query-best-practices-with-eslint
3
+ description: >
4
+ Use this when configuring @tanstack/eslint-plugin-query, flat/recommended,
5
+ flat/recommended-strict, exhaustive-deps, no-rest-destructuring,
6
+ no-unstable-deps, no-void-query-fn, stable-query-client, prefer-query-options,
7
+ infinite-query-property-order, and mutation-property-order.
8
+ type: composition
9
+ library: TanStack Query
10
+ library_version: "5.101.0"
11
+ requires:
12
+ - core/design-query-keys-and-options
13
+ - core/fetch-and-observe-queries
14
+ - framework/shape-data-and-render-efficiently
15
+ sources:
16
+ - TanStack/query:docs/eslint/eslint-plugin-query.md
17
+ - TanStack/query:docs/eslint/exhaustive-deps.md
18
+ - TanStack/query:docs/eslint/no-rest-destructuring.md
19
+ - TanStack/query:docs/eslint/no-unstable-deps.md
20
+ - TanStack/query:docs/eslint/no-void-query-fn.md
21
+ - TanStack/query:docs/eslint/prefer-query-options.md
22
+ - TanStack/query:docs/eslint/stable-query-client.md
23
+ - TanStack/query:docs/eslint/infinite-query-property-order.md
24
+ - TanStack/query:docs/eslint/mutation-property-order.md
25
+ ---
26
+
27
+ ## Setup
28
+
29
+ ```js
30
+ import pluginQuery from "@tanstack/eslint-plugin-query";
31
+
32
+ export default [...pluginQuery.configs["flat/recommended"]];
33
+ ```
34
+
35
+ ## Core Integration Patterns
36
+
37
+ ### Use strict when generating Query-heavy code
38
+
39
+ ```js
40
+ import pluginQuery from "@tanstack/eslint-plugin-query";
41
+
42
+ export default [...pluginQuery.configs["flat/recommended-strict"]];
43
+ ```
44
+
45
+ ### Prefer option factories
46
+
47
+ ```ts
48
+ import { queryOptions, useQuery } from "@tanstack/react-query";
49
+
50
+ const todosOptions = queryOptions({
51
+ queryKey: ["todos"],
52
+ queryFn: async () => [{ id: 1 }],
53
+ });
54
+
55
+ export function useTodos() {
56
+ return useQuery(todosOptions);
57
+ }
58
+ ```
59
+
60
+ ### Keep inference-sensitive property order
61
+
62
+ ```ts
63
+ import { useInfiniteQuery } from "@tanstack/react-query";
64
+
65
+ export function useFeed() {
66
+ return useInfiniteQuery({
67
+ queryKey: ["feed"],
68
+ queryFn: async ({ pageParam }) => ({ nextCursor: pageParam + 1 }),
69
+ initialPageParam: 0,
70
+ getNextPageParam: (page) => page.nextCursor,
71
+ });
72
+ }
73
+ ```
74
+
75
+ ## Common Mistakes
76
+
77
+ ### MEDIUM Strict rule not enabled
78
+
79
+ Wrong:
80
+
81
+ ```js
82
+ import pluginQuery from "@tanstack/eslint-plugin-query";
83
+
84
+ export default [...pluginQuery.configs["flat/recommended"]];
85
+ ```
86
+
87
+ Correct:
88
+
89
+ ```js
90
+ import pluginQuery from "@tanstack/eslint-plugin-query";
91
+
92
+ export default [...pluginQuery.configs["flat/recommended-strict"]];
93
+ ```
94
+
95
+ Strict mode catches option-factory and inference patterns that agents commonly miss.
96
+
97
+ Source: TanStack/query:docs/eslint/eslint-plugin-query.md
98
+
99
+ ### MEDIUM Infinite option property order
100
+
101
+ Wrong:
102
+
103
+ ```ts
104
+ import { useInfiniteQuery } from "@tanstack/react-query";
105
+
106
+ export function useFeed() {
107
+ return useInfiniteQuery({
108
+ queryFn: async () => ({ nextCursor: 1 }),
109
+ queryKey: ["feed"],
110
+ getNextPageParam: (page) => page.nextCursor,
111
+ initialPageParam: 0,
112
+ });
113
+ }
114
+ ```
115
+
116
+ Correct:
117
+
118
+ ```ts
119
+ import { useInfiniteQuery } from "@tanstack/react-query";
120
+
121
+ export function useFeed() {
122
+ return useInfiniteQuery({
123
+ queryKey: ["feed"],
124
+ queryFn: async ({ pageParam }) => ({ nextCursor: pageParam + 1 }),
125
+ initialPageParam: 0,
126
+ getNextPageParam: (page) => page.nextCursor,
127
+ });
128
+ }
129
+ ```
130
+
131
+ Some infinite-query inference depends on stable option ordering.
132
+
133
+ Source: TanStack/query:docs/eslint/infinite-query-property-order.md
134
+
135
+ ### MEDIUM Mutation option property order
136
+
137
+ Wrong:
138
+
139
+ ```ts
140
+ import { useMutation } from "@tanstack/react-query";
141
+
142
+ export function useSave() {
143
+ return useMutation({
144
+ onSuccess: () => console.log("saved"),
145
+ mutationFn: async (title: string) => title,
146
+ });
147
+ }
148
+ ```
149
+
150
+ Correct:
151
+
152
+ ```ts
153
+ import { useMutation } from "@tanstack/react-query";
154
+
155
+ export function useSave() {
156
+ return useMutation({
157
+ mutationFn: async (title: string) => title,
158
+ onSuccess: () => console.log("saved"),
159
+ });
160
+ }
161
+ ```
162
+
163
+ The mutation property order rule preserves inference for mutation options.
164
+
165
+ Source: TanStack/query:docs/eslint/mutation-property-order.md
166
+
167
+ See also: `core/design-query-keys-and-options` for the patterns these rules protect.