@hitch42/applet 0.1.1-beta.1 → 0.1.1-beta.10
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/dist/_internal/client.js +120 -11
- package/dist/_internal/log-context.d.ts +34 -0
- package/dist/_internal/log-context.js +2 -0
- package/dist/_internal/server.d.ts +14 -1
- package/dist/_internal/server.js +122 -118
- package/dist/applet.js +53 -29
- package/dist/build-Bh_S5BUv.js +2 -0
- package/dist/{build-Rk3xDZV7.js → build-CEfFoIZZ.js} +30 -14
- package/dist/ci-BKw14X2h.js +69 -0
- package/dist/client.d.ts +3 -3
- package/dist/{contract-DMrpbaLJ.d.ts → contract-CsUpTBe0.d.ts} +1 -1
- package/dist/{deploy-D3BGDqgC.js → deploy-wGYjwXrx.js} +249 -35
- package/dist/email-DBTVhNB_.js +62 -0
- package/dist/{generate-CH0VQmUi.js → generate-BEIYs17x.js} +79 -25
- package/dist/generate-Dox-OYt6.js +2 -0
- package/dist/headers-DkNr9MLJ.js +17 -0
- package/dist/index.d.ts +123 -11
- package/dist/index.js +142 -26
- package/dist/{init-BS1Y-eNL.js → init-6oGPM46R.js} +17 -18
- package/dist/load-config-xEdTXs0y.js +27 -0
- package/dist/log-context-zu8U9Sjm.js +73 -0
- package/dist/login-CUx3TmFQ.js +12 -0
- package/dist/{logs-m00pzr_O.js → logs-DSjuEN0Q.js} +20 -22
- package/dist/{manifest-BQCAxATS.d.ts → manifest-C6_F4bL8.d.ts} +9 -0
- package/dist/{manifest-DyoJ1MIL.js → manifest-CJSL9GuC.js} +25 -3
- package/dist/me-BW7Paary.js +32 -0
- package/dist/{project-CxN-Dtc7.js → project-BRZGd6xq.js} +227 -34
- package/dist/prompt-ChS-grYO.js +29 -0
- package/dist/query-cache-CXmAyLv3.js +82 -0
- package/dist/react.d.ts +3 -2
- package/dist/react.js +98 -80
- package/dist/schedules-C8_Svr4h.js +42 -0
- package/dist/server.d.ts +9 -4
- package/dist/server.js +29 -8
- package/dist/telephony-protocol-D-nf3Gca.d.ts +76 -0
- package/dist/telephony.d.ts +97 -0
- package/dist/telephony.js +726 -0
- package/dist/{upload-YbRKEqR6.d.ts → upload-DKZzz5kW.d.ts} +6 -6
- package/dist/{variables-CP7Ce3Np.js → variables-DT5RyHdH.js} +14 -39
- package/dist/vite.d.ts +3 -60
- package/dist/vite.js +503 -34
- package/dist/workflow-engine-BOTzURKM.js +111 -0
- package/dist/{auth-DaVK0k5R.js → workspace-D0dnnlxL.js} +75 -40
- package/package.json +19 -6
- package/scaffold/.agents/skills/hitch-applets/SKILL.md +60 -15
- package/scaffold/.agents/skills/hitch-applets/references/email-tracking.md +49 -0
- package/scaffold/.agents/skills/hitch-applets/references/files.md +3 -3
- package/scaffold/.agents/skills/hitch-applets/references/manifest.md +29 -2
- package/scaffold/.agents/skills/hitch-applets/references/markdown.md +2 -0
- package/scaffold/.agents/skills/hitch-applets/references/performance.md +74 -0
- package/scaffold/.agents/skills/hitch-applets/references/records.md +32 -8
- package/scaffold/.agents/skills/hitch-applets/references/schedules.md +7 -2
- package/scaffold/.agents/skills/hitch-applets/references/server.md +0 -3
- package/scaffold/.agents/skills/hitch-applets/references/workflows.md +11 -3
- package/scaffold/.agents/skills/hitch-cli/SKILL.md +129 -0
- package/scaffold/.agents/skills/hitch-data/SKILL.md +52 -0
- package/scaffold/.agents/skills/hitch-data/references/attributes.md +127 -0
- package/scaffold/.agents/skills/hitch-data/references/limits.md +64 -0
- package/scaffold/.agents/skills/hitch-theory/SKILL.md +151 -0
- package/scaffold/.agents/skills/react-best-practices/SKILL.md +127 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-effect-event-deps.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-init-once.md +42 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-defer-await.md +82 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-dependencies.md +48 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-parallel.md +24 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-analyzable-paths.md +42 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-barrel-imports.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-conditional.md +35 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-defer-third-party.md +46 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-dynamic-imports.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-preload.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-event-listeners.md +78 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-localstorage-schema.md +74 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-batch-dom-css.md +110 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-function-results.md +58 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-storage.md +56 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-flatmap-filter.md +51 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-length-check-first.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-request-idle-callback.md +104 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-conditional-render.md +32 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-hoist-jsx.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-resource-hints.md +81 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-script-defer-async.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-usetransition-loading.md +43 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-functional-setstate.md +77 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-lazy-state-init.md +56 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo-with-default-value.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-no-inline-components.md +75 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/scaffold/.agents/skills/tanstack-query/SKILL.md +136 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/automatic-invalidation-after-mutations.md +124 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/broadcast-realtime-and-multi-tab-synchronization.md +150 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/compose-query-with-tanstack-router-and-start.md +248 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/enforce-query-best-practices-with-eslint.md +167 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/persist-offline-and-restore-caches.md +181 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/query-data-and-forms.md +156 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/build-query-abstractions.md +130 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/cancel-queries-and-consume-abort-signals.md +176 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/concurrent-optimistic-updates.md +135 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/coordinate-query-execution.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/design-query-keys-and-options.md +182 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/fetch-and-observe-queries.md +193 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/implement-optimistic-updates-and-cache-writes.md +168 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/paginate-and-build-infinite-queries.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/seed-placeholder-select-and-transform-data.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/selectors-and-derived-state.md +145 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/tune-defaults-freshness-retries-and-refetching.md +172 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/understand-query-internals-and-observers.md +104 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/write-mutations-and-invalidate-related-queries.md +183 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/debug-with-devtools.md +169 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/handle-status-and-errors.md +119 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/shape-data-and-render-efficiently.md +184 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/use-framework-adapter-reactivity.md +185 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/use-suspense-and-error-boundaries.md +208 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/migrate-major-versions-and-codemods.md +169 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/prefetch-and-remove-request-waterfalls.md +228 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/setup-query-client-and-providers.md +161 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/ssr-hydration-and-streaming.md +209 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/test-query-code.md +160 -0
- package/scaffold/.agents/skills/tanstack-router/SKILL.md +134 -0
- package/scaffold/.agents/skills/tanstack-router/references/compositions/router-query.md +412 -0
- package/scaffold/.agents/skills/tanstack-router/references/react-router.md +495 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/auth-and-guards.md +495 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/code-splitting.md +318 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/data-loading.md +490 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/index.md +158 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/navigation.md +433 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/not-found-and-errors.md +436 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/path-params.md +383 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/search-params.md +343 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/ssr.md +462 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/type-safety.md +493 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-plugin.md +250 -0
- package/scaffold/.agents/skills/tanstack-router/references/virtual-file-routes.md +215 -0
- package/scaffold/.agents/skills/web-design-guidelines/SKILL.md +184 -0
- package/scaffold/.github/workflows/hitch.yml +15 -0
- package/scaffold/AGENTS.md +2 -2
- package/scaffold/applet/src/client/components/ui/alert.tsx +1 -1
- package/scaffold/applet/src/client/components/ui/button.tsx +1 -1
- package/scaffold/applet/src/client/components/ui/checkbox.tsx +1 -1
- package/scaffold/applet/src/client/components/ui/dialog.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/dropdown-menu.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/input-group.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/select.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/sheet.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/spinner.tsx +2 -1
- package/scaffold/applet/src/client/components/ui/tabs.tsx +1 -1
- package/scaffold/applet/src/client/lib/utils.ts +1 -6
- package/scaffold/applet/src/client/styles/globals.css +2 -0
- package/dist/build-CEku1lyb.js +0 -2
- package/dist/generate-6Nbt7uii.js +0 -2
- package/dist/load-config-BnxocLAQ.js +0 -56
package/scaffold/.agents/skills/tanstack-query/references/framework/handle-status-and-errors.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: framework/handle-status-and-errors
|
|
3
|
+
description: >
|
|
4
|
+
Use this when designing TanStack Query loading, empty, stale, background error,
|
|
5
|
+
retry, toast, throwOnError, and Error Boundary flows. Covers status versus
|
|
6
|
+
fetchStatus, stale data after failed refetches, global QueryCache or
|
|
7
|
+
MutationCache error callbacks, and local versus boundary-level error handling.
|
|
8
|
+
type: framework
|
|
9
|
+
library: TanStack Query
|
|
10
|
+
library_version: "5.101.0"
|
|
11
|
+
requires:
|
|
12
|
+
- core/fetch-and-observe-queries
|
|
13
|
+
- framework/use-suspense-and-error-boundaries
|
|
14
|
+
sources:
|
|
15
|
+
- TanStack/query:docs/framework/react/guides/queries.md
|
|
16
|
+
- TanStack/query:docs/framework/react/reference/QueryErrorResetBoundary.md
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Core Patterns
|
|
20
|
+
|
|
21
|
+
Prefer data-first rendering when stale data is useful. A failed background refetch can produce `isError` while `data` is still available.
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
const todos = useQuery({ queryKey: ["todos"], queryFn: fetchTodos });
|
|
25
|
+
|
|
26
|
+
if (todos.data) return <TodoList todos={todos.data} isRefreshing={todos.isFetching} />;
|
|
27
|
+
if (todos.isPending) return <Spinner />;
|
|
28
|
+
if (todos.isError) return <ErrorMessage error={todos.error} />;
|
|
29
|
+
return null;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Use `throwOnError` when render-time Error Boundaries should own the fallback:
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
useQuery({
|
|
36
|
+
queryKey: ["todos"],
|
|
37
|
+
queryFn: fetchTodos,
|
|
38
|
+
throwOnError: (error) => error.status >= 500,
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Use global cache callbacks for cross-cutting notifications:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { QueryCache, QueryClient } from "@tanstack/react-query";
|
|
46
|
+
|
|
47
|
+
const queryClient = new QueryClient({
|
|
48
|
+
queryCache: new QueryCache({
|
|
49
|
+
onError: (error, query) => {
|
|
50
|
+
if (query.state.data !== undefined) showToast(error.message);
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Common Mistakes
|
|
57
|
+
|
|
58
|
+
### HIGH Hiding stale data on background error
|
|
59
|
+
|
|
60
|
+
Wrong:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
if (query.isError) return <ErrorMessage error={query.error} />;
|
|
64
|
+
if (query.data) return <Todos todos={query.data} />;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Correct:
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
if (query.data) return <Todos todos={query.data} staleError={query.isError ? query.error : null} />;
|
|
71
|
+
if (query.isError) return <ErrorMessage error={query.error} />;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Background refetch failures should not necessarily erase already-rendered data.
|
|
75
|
+
|
|
76
|
+
### HIGH Sending validation errors to a global boundary
|
|
77
|
+
|
|
78
|
+
Wrong:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
useMutation({ mutationFn: submitForm, throwOnError: true });
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Correct:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
useMutation({
|
|
88
|
+
mutationFn: submitForm,
|
|
89
|
+
throwOnError: (error) => error.status >= 500,
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Handle expected 4xx validation errors near the form. Send unexpected server failures to the boundary.
|
|
94
|
+
|
|
95
|
+
### MEDIUM Duplicating toast notifications per observer
|
|
96
|
+
|
|
97
|
+
Wrong:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
useQuery({
|
|
101
|
+
queryKey: ["todos"],
|
|
102
|
+
queryFn: fetchTodos,
|
|
103
|
+
onError: toastError,
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Correct:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
new QueryClient({
|
|
111
|
+
queryCache: new QueryCache({
|
|
112
|
+
onError: (error, query) => {
|
|
113
|
+
if (query.state.data !== undefined) toastError(error);
|
|
114
|
+
},
|
|
115
|
+
}),
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Observer-level callbacks can duplicate notifications across components. Use cache-level callbacks for global side effects.
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: framework/shape-data-and-render-efficiently
|
|
3
|
+
description: >
|
|
4
|
+
Use this when optimizing TanStack Query rendering with structuralSharing,
|
|
5
|
+
tracked properties, select, notifyOnChangeProps, stable hook deps, immutable
|
|
6
|
+
data, Vue reactivity, and no-rest-destructuring or no-unstable-deps lint rules.
|
|
7
|
+
type: framework
|
|
8
|
+
library: TanStack Query
|
|
9
|
+
framework: cross-adapter
|
|
10
|
+
library_version: "5.101.0"
|
|
11
|
+
requires:
|
|
12
|
+
- core/fetch-and-observe-queries
|
|
13
|
+
- core/seed-placeholder-select-and-transform-data
|
|
14
|
+
sources:
|
|
15
|
+
- TanStack/query:docs/framework/react/guides/render-optimizations.md
|
|
16
|
+
- TanStack/query:docs/eslint/no-rest-destructuring.md
|
|
17
|
+
- TanStack/query:docs/eslint/no-unstable-deps.md
|
|
18
|
+
- TanStack/query:docs/framework/vue/reactivity.md
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
This skill builds on `core/fetch-and-observe-queries` and `core/seed-placeholder-select-and-transform-data`.
|
|
22
|
+
|
|
23
|
+
## Setup
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { useQuery } from "@tanstack/react-query";
|
|
27
|
+
|
|
28
|
+
export function TodoCount() {
|
|
29
|
+
const { data } = useQuery({
|
|
30
|
+
queryKey: ["todos"],
|
|
31
|
+
queryFn: async () => [{ id: 1 }, { id: 2 }],
|
|
32
|
+
select: (todos) => todos.length,
|
|
33
|
+
});
|
|
34
|
+
return <p>{data ?? 0}</p>;
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Hooks and Components
|
|
39
|
+
|
|
40
|
+
### Destructure only used result fields
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { useQuery } from "@tanstack/react-query";
|
|
44
|
+
|
|
45
|
+
export function Todos() {
|
|
46
|
+
const { data, isFetching } = useQuery({
|
|
47
|
+
queryKey: ["todos"],
|
|
48
|
+
queryFn: async () => [{ id: 1 }],
|
|
49
|
+
});
|
|
50
|
+
return (
|
|
51
|
+
<pre>
|
|
52
|
+
{isFetching ? "Refreshing " : ""}
|
|
53
|
+
{JSON.stringify(data ?? [])}
|
|
54
|
+
</pre>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Keep Vue query data immutable
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { ref } from "vue";
|
|
63
|
+
|
|
64
|
+
export function editableTodo(todo: { id: number; title: string }) {
|
|
65
|
+
return ref({ ...todo });
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Use stable members in deps
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
import * as React from "react";
|
|
73
|
+
import { useQuery } from "@tanstack/react-query";
|
|
74
|
+
|
|
75
|
+
export function TodosEffect() {
|
|
76
|
+
const { data } = useQuery({
|
|
77
|
+
queryKey: ["todos"],
|
|
78
|
+
queryFn: async () => [{ id: 1 }],
|
|
79
|
+
});
|
|
80
|
+
React.useEffect(() => console.log(data?.length ?? 0), [data]);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Common Mistakes
|
|
86
|
+
|
|
87
|
+
### MEDIUM Rest destructuring
|
|
88
|
+
|
|
89
|
+
Wrong:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { useQuery } from "@tanstack/react-query";
|
|
93
|
+
|
|
94
|
+
export function useTodos() {
|
|
95
|
+
const { data, ...rest } = useQuery({
|
|
96
|
+
queryKey: ["todos"],
|
|
97
|
+
queryFn: async () => [{ id: 1 }],
|
|
98
|
+
});
|
|
99
|
+
return { data, rest };
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Correct:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { useQuery } from "@tanstack/react-query";
|
|
107
|
+
|
|
108
|
+
export function useTodos() {
|
|
109
|
+
const { data, isFetching, error } = useQuery({
|
|
110
|
+
queryKey: ["todos"],
|
|
111
|
+
queryFn: async () => [{ id: 1 }],
|
|
112
|
+
});
|
|
113
|
+
return { data, isFetching, error };
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Rest destructuring touches every tracked property and disables fine-grained render tracking.
|
|
118
|
+
|
|
119
|
+
Source: TanStack/query:docs/eslint/no-rest-destructuring.md
|
|
120
|
+
|
|
121
|
+
### HIGH Query result in hook deps
|
|
122
|
+
|
|
123
|
+
Wrong:
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
import * as React from "react";
|
|
127
|
+
import { useQuery } from "@tanstack/react-query";
|
|
128
|
+
|
|
129
|
+
export function Todos() {
|
|
130
|
+
const query = useQuery({
|
|
131
|
+
queryKey: ["todos"],
|
|
132
|
+
queryFn: async () => [{ id: 1 }],
|
|
133
|
+
});
|
|
134
|
+
React.useEffect(() => console.log(query.data), [query]);
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Correct:
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
import * as React from "react";
|
|
143
|
+
import { useQuery } from "@tanstack/react-query";
|
|
144
|
+
|
|
145
|
+
export function Todos() {
|
|
146
|
+
const { data } = useQuery({
|
|
147
|
+
queryKey: ["todos"],
|
|
148
|
+
queryFn: async () => [{ id: 1 }],
|
|
149
|
+
});
|
|
150
|
+
React.useEffect(() => console.log(data), [data]);
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The top-level query result object is not referentially stable; destructured members are tracked.
|
|
156
|
+
|
|
157
|
+
Source: TanStack/query:docs/eslint/no-unstable-deps.md
|
|
158
|
+
|
|
159
|
+
### HIGH Vue v-model mutates query result
|
|
160
|
+
|
|
161
|
+
Wrong:
|
|
162
|
+
|
|
163
|
+
```vue
|
|
164
|
+
<script setup lang="ts">
|
|
165
|
+
const todo = { id: 1, title: "Ship" };
|
|
166
|
+
</script>
|
|
167
|
+
<template><input v-model="todo.title" /></template>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Correct:
|
|
171
|
+
|
|
172
|
+
```vue
|
|
173
|
+
<script setup lang="ts">
|
|
174
|
+
import { ref } from "vue";
|
|
175
|
+
const editableTodo = ref({ id: 1, title: "Ship" });
|
|
176
|
+
</script>
|
|
177
|
+
<template><input v-model="editableTodo.title" /></template>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Vue Query results are immutable; make a mutable copy for form state.
|
|
181
|
+
|
|
182
|
+
Source: TanStack/query:docs/framework/vue/reactivity.md
|
|
183
|
+
|
|
184
|
+
See also: `compositions/enforce-query-best-practices-with-eslint` for lint rules that protect render tracking.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: framework/use-framework-adapter-reactivity
|
|
3
|
+
description: >
|
|
4
|
+
Use this when translating Query patterns across React, Preact, Vue, Solid,
|
|
5
|
+
Svelte, Angular, and Lit adapters: Vue refs/getters, Solid signals, Svelte
|
|
6
|
+
stores/runes, Angular signals and HttpClient promises, Lit QueryController,
|
|
7
|
+
adapter option helpers, and provider APIs.
|
|
8
|
+
type: framework
|
|
9
|
+
library: TanStack Query
|
|
10
|
+
framework: cross-adapter
|
|
11
|
+
library_version: "5.101.0"
|
|
12
|
+
requires:
|
|
13
|
+
- lifecycle/setup-query-client-and-providers
|
|
14
|
+
- core/design-query-keys-and-options
|
|
15
|
+
sources:
|
|
16
|
+
- TanStack/query:docs/framework/vue/reactivity.md
|
|
17
|
+
- TanStack/query:docs/framework/vue/guides/query-options.md
|
|
18
|
+
- TanStack/query:docs/framework/solid/guides/query-options.md
|
|
19
|
+
- TanStack/query:docs/framework/svelte/overview.md
|
|
20
|
+
- TanStack/query:docs/framework/svelte/migrate-from-v5-to-v6.md
|
|
21
|
+
- TanStack/query:docs/framework/angular/overview.md
|
|
22
|
+
- TanStack/query:docs/framework/angular/zoneless.md
|
|
23
|
+
- TanStack/query:docs/framework/lit/guides/reactive-controllers-vs-hooks.md
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
This skill builds on `lifecycle/setup-query-client-and-providers` and `core/design-query-keys-and-options`.
|
|
27
|
+
|
|
28
|
+
## Setup
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { queryOptions } from "@tanstack/react-query";
|
|
32
|
+
|
|
33
|
+
export function todoOptions(id: string) {
|
|
34
|
+
return queryOptions({
|
|
35
|
+
queryKey: ["todo", id],
|
|
36
|
+
queryFn: async () => ({ id }),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Hooks and Components
|
|
42
|
+
|
|
43
|
+
### Keep Vue refs in the key
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { computed, toRef } from "vue";
|
|
47
|
+
import { useQuery } from "@tanstack/vue-query";
|
|
48
|
+
|
|
49
|
+
export function useTodo(props: { id: string }) {
|
|
50
|
+
const id = toRef(props, "id");
|
|
51
|
+
return useQuery(
|
|
52
|
+
computed(() => ({
|
|
53
|
+
queryKey: ["todo", id.value],
|
|
54
|
+
queryFn: async () => ({ id: id.value }),
|
|
55
|
+
})),
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Use Solid option functions
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { createQuery } from "@tanstack/solid-query";
|
|
64
|
+
|
|
65
|
+
export function useTodo(id: () => string) {
|
|
66
|
+
return createQuery(() => ({
|
|
67
|
+
queryKey: ["todo", id()],
|
|
68
|
+
queryFn: async () => ({ id: id() }),
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Convert Angular Observable clients to promises
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { injectQuery } from "@tanstack/angular-query-experimental";
|
|
77
|
+
import { firstValueFrom, of } from "rxjs";
|
|
78
|
+
|
|
79
|
+
export class TodosQuery {
|
|
80
|
+
todos = injectQuery(() => ({
|
|
81
|
+
queryKey: ["todos"],
|
|
82
|
+
queryFn: () => firstValueFrom(of([{ id: 1 }])),
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Common Mistakes
|
|
88
|
+
|
|
89
|
+
### HIGH Vue ref unwrapped
|
|
90
|
+
|
|
91
|
+
Wrong:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { useQuery } from "@tanstack/vue-query";
|
|
95
|
+
|
|
96
|
+
export function useTodo(id: { value: string }) {
|
|
97
|
+
return useQuery({
|
|
98
|
+
queryKey: ["todo", id.value],
|
|
99
|
+
queryFn: async () => ({ id: id.value }),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Correct:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import { computed } from "vue";
|
|
108
|
+
import { useQuery } from "@tanstack/vue-query";
|
|
109
|
+
|
|
110
|
+
export function useTodo(id: { value: string }) {
|
|
111
|
+
return useQuery(
|
|
112
|
+
computed(() => ({
|
|
113
|
+
queryKey: ["todo", id.value],
|
|
114
|
+
queryFn: async () => ({ id: id.value }),
|
|
115
|
+
})),
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Vue reactive inputs need to stay reactive through the options object or query key.
|
|
121
|
+
|
|
122
|
+
Source: TanStack/query:docs/framework/vue/reactivity.md
|
|
123
|
+
|
|
124
|
+
### HIGH Svelte store syntax in v6
|
|
125
|
+
|
|
126
|
+
Wrong:
|
|
127
|
+
|
|
128
|
+
```svelte
|
|
129
|
+
<script lang="ts">
|
|
130
|
+
import { createQuery } from '@tanstack/svelte-query'
|
|
131
|
+
const query = createQuery({ queryKey: ['todos'], queryFn: async () => [] })
|
|
132
|
+
</script>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Correct:
|
|
136
|
+
|
|
137
|
+
```svelte
|
|
138
|
+
<script lang="ts">
|
|
139
|
+
import { createQuery } from '@tanstack/svelte-query'
|
|
140
|
+
const query = createQuery(() => ({
|
|
141
|
+
queryKey: ['todos'],
|
|
142
|
+
queryFn: async () => [],
|
|
143
|
+
}))
|
|
144
|
+
</script>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Svelte Query v6 uses rune-compatible option functions rather than the older store shape.
|
|
148
|
+
|
|
149
|
+
Source: TanStack/query:docs/framework/svelte/migrate-from-v5-to-v6.md
|
|
150
|
+
|
|
151
|
+
### HIGH Angular Observable returned directly
|
|
152
|
+
|
|
153
|
+
Wrong:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { injectQuery } from "@tanstack/angular-query-experimental";
|
|
157
|
+
import { of } from "rxjs";
|
|
158
|
+
|
|
159
|
+
export class TodosQuery {
|
|
160
|
+
todos = injectQuery(() => ({
|
|
161
|
+
queryKey: ["todos"],
|
|
162
|
+
queryFn: () => of([{ id: 1 }]),
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Correct:
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
import { injectQuery } from "@tanstack/angular-query-experimental";
|
|
171
|
+
import { firstValueFrom, of } from "rxjs";
|
|
172
|
+
|
|
173
|
+
export class TodosQuery {
|
|
174
|
+
todos = injectQuery(() => ({
|
|
175
|
+
queryKey: ["todos"],
|
|
176
|
+
queryFn: () => firstValueFrom(of([{ id: 1 }])),
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Query functions must resolve data; Angular HttpClient Observables need conversion to promises.
|
|
182
|
+
|
|
183
|
+
Source: TanStack/query:docs/framework/angular/angular-httpclient-and-other-data-fetching-clients.md
|
|
184
|
+
|
|
185
|
+
See also: `core/design-query-keys-and-options` for key identity across adapters.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: framework/use-suspense-and-error-boundaries
|
|
3
|
+
description: >
|
|
4
|
+
Use this when using useSuspenseQuery, useSuspenseQueries,
|
|
5
|
+
useSuspenseInfiniteQuery, QueryErrorResetBoundary, throwOnError,
|
|
6
|
+
useQueryErrorResetBoundary, React.use query.promise, streamed hydration, and
|
|
7
|
+
Suspense constraints in Query adapters.
|
|
8
|
+
type: framework
|
|
9
|
+
library: TanStack Query
|
|
10
|
+
framework: cross-adapter
|
|
11
|
+
library_version: "5.101.0"
|
|
12
|
+
requires:
|
|
13
|
+
- core/fetch-and-observe-queries
|
|
14
|
+
- lifecycle/prefetch-and-remove-request-waterfalls
|
|
15
|
+
sources:
|
|
16
|
+
- TanStack/query:docs/framework/react/guides/suspense.md
|
|
17
|
+
- TanStack/query:docs/framework/react/reference/QueryErrorResetBoundary.md
|
|
18
|
+
- TanStack/query:docs/framework/react/reference/useSuspenseQuery.md
|
|
19
|
+
- TanStack/query:docs/framework/react/reference/useSuspenseQueries.md
|
|
20
|
+
- TanStack/query:docs/framework/react/reference/useSuspenseInfiniteQuery.md
|
|
21
|
+
- TanStack/query:docs/framework/solid/guides/suspense.md
|
|
22
|
+
- TanStack/query:docs/framework/vue/guides/suspense.md
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This skill builds on `core/fetch-and-observe-queries` and `lifecycle/prefetch-and-remove-request-waterfalls`.
|
|
26
|
+
|
|
27
|
+
## Setup
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { Suspense } from "react";
|
|
31
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
32
|
+
|
|
33
|
+
function Todos() {
|
|
34
|
+
const { data } = useSuspenseQuery({
|
|
35
|
+
queryKey: ["todos"],
|
|
36
|
+
queryFn: async () => [{ id: 1 }],
|
|
37
|
+
});
|
|
38
|
+
return <pre>{JSON.stringify(data)}</pre>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function App() {
|
|
42
|
+
return (
|
|
43
|
+
<Suspense fallback={<p>Loading</p>}>
|
|
44
|
+
<Todos />
|
|
45
|
+
</Suspense>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Hooks and Components
|
|
51
|
+
|
|
52
|
+
### Reset query errors with the boundary
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { QueryErrorResetBoundary } from "@tanstack/react-query";
|
|
56
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
57
|
+
|
|
58
|
+
export function QueryErrorBoundary(props: { children: React.ReactNode }) {
|
|
59
|
+
return (
|
|
60
|
+
<QueryErrorResetBoundary>
|
|
61
|
+
{({ reset }) => (
|
|
62
|
+
<ErrorBoundary
|
|
63
|
+
onReset={reset}
|
|
64
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
65
|
+
<button onClick={resetErrorBoundary}>Retry</button>
|
|
66
|
+
)}
|
|
67
|
+
>
|
|
68
|
+
{props.children}
|
|
69
|
+
</ErrorBoundary>
|
|
70
|
+
)}
|
|
71
|
+
</QueryErrorResetBoundary>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Use suspense when data must be defined
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
80
|
+
|
|
81
|
+
export function useTodos() {
|
|
82
|
+
return useSuspenseQuery({
|
|
83
|
+
queryKey: ["todos"],
|
|
84
|
+
queryFn: async () => [{ id: 1 }],
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Use normal queries for disabled flows
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { useQuery } from "@tanstack/react-query";
|
|
93
|
+
|
|
94
|
+
export function useMaybeTodo(id: string | undefined) {
|
|
95
|
+
return useQuery({
|
|
96
|
+
queryKey: ["todo", id],
|
|
97
|
+
queryFn: async () => ({ id }),
|
|
98
|
+
enabled: Boolean(id),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Common Mistakes
|
|
104
|
+
|
|
105
|
+
### HIGH Disabled suspense query
|
|
106
|
+
|
|
107
|
+
Wrong:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
111
|
+
|
|
112
|
+
export function useTodo(id: string | undefined) {
|
|
113
|
+
return useSuspenseQuery({
|
|
114
|
+
queryKey: ["todo", id],
|
|
115
|
+
queryFn: async () => ({ id }),
|
|
116
|
+
enabled: Boolean(id),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Correct:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
import { useQuery } from "@tanstack/react-query";
|
|
125
|
+
|
|
126
|
+
export function useTodo(id: string | undefined) {
|
|
127
|
+
return useQuery({
|
|
128
|
+
queryKey: ["todo", id],
|
|
129
|
+
queryFn: async () => ({ id }),
|
|
130
|
+
enabled: Boolean(id),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Suspense hooks guarantee `data` and do not support conditional disabling like normal queries.
|
|
136
|
+
|
|
137
|
+
Source: TanStack/query:docs/framework/react/guides/suspense.md
|
|
138
|
+
|
|
139
|
+
### HIGH Missing reset boundary
|
|
140
|
+
|
|
141
|
+
Wrong:
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
145
|
+
|
|
146
|
+
export function Todos() {
|
|
147
|
+
const { data } = useSuspenseQuery({
|
|
148
|
+
queryKey: ["todos"],
|
|
149
|
+
queryFn: async () => [{ id: 1 }],
|
|
150
|
+
});
|
|
151
|
+
return <pre>{JSON.stringify(data)}</pre>;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Correct:
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
import { QueryErrorResetBoundary } from "@tanstack/react-query";
|
|
159
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
160
|
+
|
|
161
|
+
export function WrappedTodos(props: { children: React.ReactNode }) {
|
|
162
|
+
return (
|
|
163
|
+
<QueryErrorResetBoundary>
|
|
164
|
+
{({ reset }) => (
|
|
165
|
+
<ErrorBoundary onReset={reset} fallback={<p>Error</p>}>
|
|
166
|
+
{props.children}
|
|
167
|
+
</ErrorBoundary>
|
|
168
|
+
)}
|
|
169
|
+
</QueryErrorResetBoundary>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Error boundaries need Query reset coordination so failed queries can retry after reset.
|
|
175
|
+
|
|
176
|
+
Source: TanStack/query:docs/framework/react/reference/QueryErrorResetBoundary.md
|
|
177
|
+
|
|
178
|
+
### MEDIUM query.promise without flag
|
|
179
|
+
|
|
180
|
+
Wrong:
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
import { useQuery } from "@tanstack/react-query";
|
|
184
|
+
|
|
185
|
+
export function useTodoPromise() {
|
|
186
|
+
return useQuery({ queryKey: ["todo", 1], queryFn: async () => ({ id: 1 }) }).promise;
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Correct:
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import { QueryClient, useQuery } from "@tanstack/react-query";
|
|
194
|
+
|
|
195
|
+
export const queryClient = new QueryClient({
|
|
196
|
+
defaultOptions: { queries: { experimental_prefetchInRender: true } },
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
export function useTodoPromise() {
|
|
200
|
+
return useQuery({ queryKey: ["todo", 1], queryFn: async () => ({ id: 1 }) }).promise;
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The stable `promise` property requires the experimental prefetch-in-render flag.
|
|
205
|
+
|
|
206
|
+
Source: TanStack/query:docs/framework/react/guides/suspense.md
|
|
207
|
+
|
|
208
|
+
See also: `lifecycle/ssr-hydration-and-streaming` for streamed hydration constraints.
|