Skip to content

docs(solid-query): convert guide docs to ref-based with Solid-style code#10146

Open
sukvvon wants to merge 4 commits intoTanStack:mainfrom
sukvvon:docs/solid-query-guides
Open

docs(solid-query): convert guide docs to ref-based with Solid-style code#10146
sukvvon wants to merge 4 commits intoTanStack:mainfrom
sukvvon:docs/solid-query-guides

Conversation

@sukvvon
Copy link
Contributor

@sukvvon sukvvon commented Feb 18, 2026

🎯 Changes

  • Add markers to 8 React guide source files for Solid marker overrides
  • Convert 25 Solid guide docs from copy-paste to ref-based with replace rules and marker overrides
  • Rewrite all code examples in Solid style (accessor pattern, createSignal, Show/For/Switch, no destructuring)
  • Add Solid offline example entry to docs config

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

Release Notes

  • Documentation

    • Enhanced React and Solid framework guides with improved explanations of caching, mutations, query management, and performance patterns.
    • Added comprehensive code examples throughout guides demonstrating various query and mutation configurations.
  • New Examples

    • Introduced offline queries and mutations example for Solid framework, demonstrating persistent mutation patterns.

@changeset-bot
Copy link

changeset-bot bot commented Feb 18, 2026

⚠️ No Changeset found

Latest commit: 786cd36

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Feb 18, 2026
@nx-cloud
Copy link

nx-cloud bot commented Feb 18, 2026

View your CI Pipeline Execution ↗ for commit 786cd36

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 48s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2026-02-18 02:53:37 UTC

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 18, 2026

📝 Walkthrough

Walkthrough

This PR introduces a new offline mutations example for Solid Query, refactors Solid framework guides to replace migration rule mappings with concrete code examples, and adds documentation anchors and comments throughout React framework guides for improved documentation structure.

Changes

Cohort / File(s) Summary
Configuration Update
docs/config.json
Added new "Offline Queries and Mutations" example entry pointing to the new Solid offline example under framework/solid/examples/offline.
React Framework Guides - Documentation Anchors
docs/framework/react/guides/caching.md, query-options.md, queries.md, parallel-queries.md, mutations.md
Added inline documentation anchor comments (StaleNote, SelectDescription, SubscribeDescription, DynamicParallelDescription, PersistOfflineIntro) and reformatted StructuralSharing documentation for improved documentation scaffolding.
React Framework Guides - Content Updates
docs/framework/react/guides/important-defaults.md, query-cancellation.md, request-waterfalls.md
Updated documentation formatting for StructuralSharing, added Suspense hook limitations notes, and enriched request-waterfalls guide with additional anchors and explanatory content.
Solid Framework Guides - Migration Mapping Removals
docs/framework/solid/guides/background-fetching-indicators.md, caching.md, default-query-function.md, dependent-queries.md, disabling-queries.md, infinite-queries.md, placeholder-query-data.md, queries.md, query-cancellation.md, query-functions.md, query-keys.md, updates-from-mutation-responses.md, window-focus-refetching.md
Removed React-to-Solid translation mappings and replaced with concrete Solid.js code examples demonstrating equivalent patterns and usage in Solid Query.
Solid Framework Guides - New Content & Examples
docs/framework/solid/guides/initial-query-data.md, mutations.md, optimistic-updates.md, paginated-queries.md, parallel-queries.md, prefetching.md, query-options.md, query-invalidation.md, scroll-restoration.md, suspense.md
Added extensive code examples, refactored migration mappings to generic replacements, updated titles (Prefetching → Prefetching & Router Integration), introduced Router Integration patterns, and renamed variables for clarity.
Solid Framework Guides - Minor Mapping Updates
docs/framework/solid/guides/important-defaults.md, invalidations-from-mutations.md
Added StructuralSharing documentation notes and generic hook-to-function replacement mappings for example code generation.
New Solid Offline Example Project
examples/solid/offline/.eslintrc.cjs, README.md, index.html, package.json, src/App.tsx, src/api.ts, src/index.tsx, src/movies.ts, tsconfig.json, vite.config.ts
Complete new Solid.js offline mutations example demonstrating offline persistence, optimistic updates, mutation pausing/resuming, mock service worker setup, and local state management with TanStack Solid Query.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • TkDodo

Poem

🐰 Offline mutations bloom so bright,
With Solid's resilience through the night,
No more mappings to confuse the way,
Just examples showing how to play!
Paused and resumed, optimistic dreams—
Query persistence flows like streams!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: converting Solid query guide documentation to use ref-based content with Solid-style code examples.
Description check ✅ Passed The description provides concrete details about changes (8 React files marked, 25 Solid guides converted, code examples rewritten) and indicates it is docs-only with no release impact.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 18, 2026

More templates

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@10146

@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@10146

@tanstack/preact-query

npm i https://pkg.pr.new/@tanstack/preact-query@10146

@tanstack/query-async-storage-persister

npm i https://pkg.pr.new/@tanstack/query-async-storage-persister@10146

@tanstack/query-broadcast-client-experimental

npm i https://pkg.pr.new/@tanstack/query-broadcast-client-experimental@10146

@tanstack/query-core

npm i https://pkg.pr.new/@tanstack/query-core@10146

@tanstack/query-devtools

npm i https://pkg.pr.new/@tanstack/query-devtools@10146

@tanstack/query-persist-client-core

npm i https://pkg.pr.new/@tanstack/query-persist-client-core@10146

@tanstack/query-sync-storage-persister

npm i https://pkg.pr.new/@tanstack/query-sync-storage-persister@10146

@tanstack/react-query

npm i https://pkg.pr.new/@tanstack/react-query@10146

@tanstack/react-query-devtools

npm i https://pkg.pr.new/@tanstack/react-query-devtools@10146

@tanstack/react-query-next-experimental

npm i https://pkg.pr.new/@tanstack/react-query-next-experimental@10146

@tanstack/react-query-persist-client

npm i https://pkg.pr.new/@tanstack/react-query-persist-client@10146

@tanstack/solid-query

npm i https://pkg.pr.new/@tanstack/solid-query@10146

@tanstack/solid-query-devtools

npm i https://pkg.pr.new/@tanstack/solid-query-devtools@10146

@tanstack/solid-query-persist-client

npm i https://pkg.pr.new/@tanstack/solid-query-persist-client@10146

@tanstack/svelte-query

npm i https://pkg.pr.new/@tanstack/svelte-query@10146

@tanstack/svelte-query-devtools

npm i https://pkg.pr.new/@tanstack/svelte-query-devtools@10146

@tanstack/svelte-query-persist-client

npm i https://pkg.pr.new/@tanstack/svelte-query-persist-client@10146

@tanstack/vue-query

npm i https://pkg.pr.new/@tanstack/vue-query@10146

@tanstack/vue-query-devtools

npm i https://pkg.pr.new/@tanstack/vue-query-devtools@10146

commit: 786cd36

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🧹 Nitpick comments (4)
docs/framework/solid/guides/placeholder-query-data.md (1)

22-22: Heading level skip is acceptable in ref-based docs.

The h3 heading appears without a preceding h2 in this file, but since this is a ref-based document (line 4), the parent h2 sections are inherited from the React guide. This is likely intentional structure, though it causes markdownlint to flag a violation when analyzing the file in isolation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/solid/guides/placeholder-query-data.md` at line 22, Add an
explicit inline comment above the "Placeholder Data Memoization" h3 to indicate
the heading-level skip is intentional because this is a ref-based document whose
parent h2 sections are inherited from the React guide; this comment should
reference the h3 ("Placeholder Data Memoization") so reviewers and linters
understand the skip (or alternatively add a markdownlint disable directive at
the top of the file for the specific heading-level rule) to prevent the isolated
markdownlint violation.
docs/framework/solid/guides/disabling-queries.md (1)

23-38: Consider reordering Match conditions for clearer state handling.

The current order checks todosQuery.data before isError and isLoading. If data exists from a previous fetch but a refetch fails, the error state won't be displayed. This might be intentional for stale-while-revalidate UX, but typically error/loading states are checked first.

Suggested reordering for explicit state prioritization
       <Switch>
-        <Match when={todosQuery.data}>
-          <ul>
-            <For each={todosQuery.data}>{(todo) => <li>{todo.title}</li>}</For>
-          </ul>
-        </Match>
-        <Match when={todosQuery.isError}>
-          <span>Error: {todosQuery.error.message}</span>
-        </Match>
         <Match when={todosQuery.isLoading}>
           <span>Loading...</span>
         </Match>
+        <Match when={todosQuery.isError}>
+          <span>Error: {todosQuery.error.message}</span>
+        </Match>
+        <Match when={todosQuery.data}>
+          <ul>
+            <For each={todosQuery.data}>{(todo) => <li>{todo.title}</li>}</For>
+          </ul>
+        </Match>
         <Match when={true}>
           <span>Not ready ...</span>
         </Match>
       </Switch>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/solid/guides/disabling-queries.md` around lines 23 - 38, The
Switch/Match block currently checks todosQuery.data before todosQuery.isError
and todosQuery.isLoading, which can hide error/loading states when stale data
exists; reorder the Match checks in the Switch so that todosQuery.isError and
todosQuery.isLoading are evaluated before todosQuery.data (i.e., check
todosQuery.isError, then todosQuery.isLoading, then todosQuery.data, finally the
fallback Match when={true}) to ensure explicit prioritization of error/loading
states in the rendering logic for the todosQuery component.
examples/solid/offline/src/api.ts (1)

17-42: Consider adding response status checks.

The fetch functions don't verify response.ok before parsing JSON. If the server returns an error status (e.g., 404 from line 59), calling response.json() on non-JSON error bodies could throw or produce unexpected results.

Example fix for fetchMovie
 export const fetchMovie = async (
   id: string,
 ): Promise<{
   ts: number
   movie: { comment: string; id: string; title: string }
 }> => {
   const response = await fetch(`/movies/${id}`)
+  if (!response.ok) {
+    throw new Error(`Failed to fetch movie: ${response.status}`)
+  }
   return await response.json()
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/solid/offline/src/api.ts` around lines 17 - 42, The three API
helpers (fetchMovie, fetchMovies, updateMovie) don't check response.ok before
calling response.json(), so update each function to verify response.ok after
fetch; if not ok, read the response body (preferably text or safe JSON parse),
and throw an Error that includes the HTTP status and returned message/body so
callers can handle failures. Specifically, in fetchMovie, fetchMovies, and
updateMovie add a conditional like "if (!response.ok) { const errBody = await
response.text(); throw new Error(`Fetch <functionName> failed
${response.status}: ${errBody}`) }" (replace <functionName> with the real
function names) before returning response.json().
examples/solid/offline/src/movies.ts (1)

43-45: Type the error handler parameters properly.

Using any types loses type safety. Consider using proper types or at minimum a more descriptive approach.

Proposed fix
-    onError: (_: any, __: any, context: any) => {
+    onError: (_error, _variables, context) => {
       queryClient.setQueryData(movieKeys.detail(movieId), context.previousData)
     },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/solid/offline/src/movies.ts` around lines 43 - 45, The onError
handler currently uses any for all params; change it to use meaningful types
(avoid any) such as (error: unknown, variables: { movieId: string } | undefined,
context: { previousData?: Movie | null } | undefined) => {
queryClient.setQueryData(movieKeys.detail(movieId), context?.previousData) };
import or reference the Movie type used by your fetcher and/or define a small
MutationContext type for context to improve type-safety while keeping the call
to queryClient.setQueryData(movieKeys.detail(movieId), context?.previousData)
intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/framework/react/guides/request-waterfalls.md`:
- Line 187: Summary: Hyphenate compound modifiers like "real world" to
"real-world" for grammar consistency. Fix: update the prose that mentions
"<Comments>" and "<Article>" to use "real-world applications" and any other
compound modifiers (e.g., "child might be nested far below the parent" if used
as a modifier) to be hyphenated; search for occurrences around the discussion of
hoisting the comments query to the parent and at the alternate locations noted
(also applies to lines referencing 368-369) and replace plain compounds with
hyphenated forms to maintain consistent compound-adjective styling.
- Around line 272-275: The fenced code block showing the waterfall steps (the
lines containing "getFeed()" and "getGraphDataById()") is missing a language
tag; update that triple-backtick block to include a language specifier (e.g.,
"text") so Markdownlint stops warning and the snippet is properly annotated.

In `@docs/framework/solid/guides/mutations.md`:
- Line 275: The heading "Persisting Offline mutations" is an h3 (###) that skips
from the document's h1; change it to h2 (## Persisting Offline mutations) so
heading levels increment correctly per markdownlint MD001 and maintain document
structure; update the heading token for "Persisting Offline mutations" to use
two hashes and ensure nearby headings remain properly nested.
- Around line 173-190: The onSuccess callbacks in the Example7 snippet use an
incorrect four-parameter signature (data, variables, onMutateResult, context);
update both the global useMutation onSuccess and the per-call mutate onSuccess
to the correct signature used by this library (e.g., onSuccess: (data,
variables, context) => { ... }) and adjust any references to the removed
parameter (onMutateResult) accordingly; specifically edit the useMutation block
and the mutate(...) call that reference addTodo, useMutation, and mutate to use
(data, variables, context) so the docs match the real API.
- Around line 143-168: The example callbacks for useMutation and mutate use an
incorrect fourth parameter name "onMutateResult"; update all
onSuccess/onError/onSettled callback signatures in the useMutation options and
in the mutate call to match the correct mutation callback shape (three params):
onSuccess(data, variables, context), onError(error, variables, context),
onSettled(dataOrUndefined, errorOrUndefined, variables, context) — or if your
API expects three params for settled, use (data, error, context); replace any
"onMutateResult" occurrences with "context" and remove the extra parameter so
the callbacks in useMutation and mutate reference the correct symbols and
ordering.
- Around line 221-255: The callbacks provided to queryClient.setMutationDefaults
use the wrong signatures—onMutate currently expects (variables, context) and
returns a context named onMutateResult, while onSuccess/onError are declared
with an extra parameter; fix by making onMutate async (variables) => { await
queryClient.cancelQueries(['todos']); const optimisticTodo = { id: uuid(),
title: variables.title }; queryClient.setQueryData(['todos'], old => [...old,
optimisticTodo]); return { optimisticTodo } } and update onSuccess and onError
to use the proper signature (data, variables, context) => {
queryClient.setQueryData(['todos'], old => old.map/todo filtering using
context.optimisticTodo.id) } so they read context.optimisticTodo (replace uses
of onMutateResult and context.client with the returned context and the outer
queryClient respectively).

In `@docs/framework/solid/guides/prefetching.md`:
- Around line 216-253: The example uses the old constructor-style API; update it
to the v1 functional API by replacing RouterContext/createRootRoute/new Route
with createRootRoute (or createRootRouteWithContext<MyContext>() for typed
context), createRoute for individual routes, build the tree with
rootRoute.addChildren([ ...childRoutes... ]), and instantiate the router via
createRouter({ routeTree: rootRoute }); also update any usages of RouterContext
methods to the new route context hooks (e.g., useRouteContext) and ensure
loader/beforeLoad signatures match the v1 createRoute API.

In `@docs/framework/solid/guides/queries.md`:
- Around line 7-95: The MD042 warnings are caused by the inline marker comments
like [//]: # 'SubscribeDescription' and [//]: # 'Example' in the markdown; wrap
the marker blocks with markdownlint disable/enable comments (e.g. insert <!--
markdownlint-disable MD042 --> before the sequence of [//]: # '...' markers and
<!-- markdownlint-enable MD042 --> after) or convert those marker lines to a
neutral HTML comment format so MD042 is suppressed for the markers (update the
marker blocks surrounding useQuery examples and the
SubscribeDescription/Example/Example2/Example3/Example4 markers accordingly).

In `@docs/framework/solid/guides/query-cancellation.md`:
- Around line 111-120: The queryFn passed to useQuery (in the todosQuery
example) does not return the Promise from client.request so the query resolves
to undefined; update the queryFn to return the client.request call (i.e., ensure
the function passed as queryFn returns the result of client.request({ document:
query, signal })) so useQuery receives the fetched data—look for GraphQLClient,
client.request, useQuery, queryFn and todosQuery in the snippet and add the
missing return.

In `@examples/solid/offline/README.md`:
- Around line 5-6: The README references running `npm run start` but
package.json only defines the `dev` script, causing the command to fail; update
the README.md instructions to use `npm run dev` (or add a `start` script to
package.json that maps to `dev`) so the command matches the actual script
name—look for the script entries in package.json and the command lines in
README.md and make them consistent.

In `@examples/solid/offline/src/App.tsx`:
- Around line 146-153: submitForm can pass an undefined comment into
updateMovie.mutate which triggers a TypeError in api.ts when
comment.toUpperCase() is called; change submitForm to ensure a defined string is
sent (e.g., compute const safeComment = comment() ??
movieQuery.data?.movie.comment ?? "" before calling updateMovie.mutate) or
validate and coerce comment() to a string and pass that into updateMovie.mutate
so api.ts always receives a string value; update the submitForm function (and
any hook return usage of comment()) to guarantee non-undefined input to
updateMovie.mutate.

In `@examples/solid/offline/src/index.tsx`:
- Around line 6-14: worker.start() is asynchronous and currently races with
initial renders; await the worker startup before calling render so MSW is ready
to intercept requests — change the flow so you await the Promise returned by
worker.start() (referencing worker.start()) and only then call render(...) to
mount <App /> (referencing render and App) to eliminate the race condition.

In `@examples/solid/offline/src/movies.ts`:
- Around line 22-42: In updateMovie's onMutate handler capture the current
comment value into a local variable before calling setComment(undefined) so the
optimistic update uses the preserved value; specifically, inside the onMutate
for updateMovie (which uses movieKeys.detail(movieId)) read comment() into e.g.
previousComment, then call setComment(undefined), and pass previousComment into
queryClient.setQueryData(...) when setting movie.comment and return
previousComment in the mutation context so rollback can restore it if needed.

---

Duplicate comments:
In `@docs/framework/solid/guides/optimistic-updates.md`:
- Around line 101-129: The mutation callbacks use a `context.client` API that
may not match Solid Query's actual context shape; verify and update
useMutation's callbacks (onMutate, onError, onSettled) to use the correct
context object and method names (e.g., confirm whether cancelQueries,
getQueryData, setQueryData, invalidateQueries are accessed via context.client or
directly via context or a queryClient provided by useMutation), then adjust
references to newTodo/onMutateResult accordingly so onMutate returns the proper
snapshot shape and onError/onSettled read that shape correctly (ensure functions
like cancelQueries(['todos', newTodo.id]) and setQueryData/getQueryData use the
actual API signature and key format used by Solid Query).

---

Nitpick comments:
In `@docs/framework/solid/guides/disabling-queries.md`:
- Around line 23-38: The Switch/Match block currently checks todosQuery.data
before todosQuery.isError and todosQuery.isLoading, which can hide error/loading
states when stale data exists; reorder the Match checks in the Switch so that
todosQuery.isError and todosQuery.isLoading are evaluated before todosQuery.data
(i.e., check todosQuery.isError, then todosQuery.isLoading, then
todosQuery.data, finally the fallback Match when={true}) to ensure explicit
prioritization of error/loading states in the rendering logic for the todosQuery
component.

In `@docs/framework/solid/guides/placeholder-query-data.md`:
- Line 22: Add an explicit inline comment above the "Placeholder Data
Memoization" h3 to indicate the heading-level skip is intentional because this
is a ref-based document whose parent h2 sections are inherited from the React
guide; this comment should reference the h3 ("Placeholder Data Memoization") so
reviewers and linters understand the skip (or alternatively add a markdownlint
disable directive at the top of the file for the specific heading-level rule) to
prevent the isolated markdownlint violation.

In `@examples/solid/offline/src/api.ts`:
- Around line 17-42: The three API helpers (fetchMovie, fetchMovies,
updateMovie) don't check response.ok before calling response.json(), so update
each function to verify response.ok after fetch; if not ok, read the response
body (preferably text or safe JSON parse), and throw an Error that includes the
HTTP status and returned message/body so callers can handle failures.
Specifically, in fetchMovie, fetchMovies, and updateMovie add a conditional like
"if (!response.ok) { const errBody = await response.text(); throw new
Error(`Fetch <functionName> failed ${response.status}: ${errBody}`) }" (replace
<functionName> with the real function names) before returning response.json().

In `@examples/solid/offline/src/movies.ts`:
- Around line 43-45: The onError handler currently uses any for all params;
change it to use meaningful types (avoid any) such as (error: unknown,
variables: { movieId: string } | undefined, context: { previousData?: Movie |
null } | undefined) => { queryClient.setQueryData(movieKeys.detail(movieId),
context?.previousData) }; import or reference the Movie type used by your
fetcher and/or define a small MutationContext type for context to improve
type-safety while keeping the call to
queryClient.setQueryData(movieKeys.detail(movieId), context?.previousData)
intact.


[//]: # 'NestedExample'

Note that while `<Comments>` takes a prop `id` from the parent, that id is already available when the `<Article>` renders so there is no reason we could not fetch the comments at the same time as the article. In real world applications, the child might be nested far below the parent and these kinds of waterfalls are often trickier to spot and fix, but for our example, one way to flatten the waterfall would be to hoist the comments query to the parent instead:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Hyphenate compound modifiers for grammar consistency.

These read as compound adjectives and should be hyphenated.

✍️ Suggested edits
- In real world applications, the child might be nested far below the parent
+ In real-world applications, the child might be nested far below the parent

- - Include all data fetching code in the main bundle, even if we seldom use it
- - Put the data fetching code in the code split bundle, but with a request waterfall
+ - Include all data-fetching code in the main bundle, even if we seldom use it
+ - Put the data-fetching code in the code-split bundle, but with a request-waterfall

Also applies to: 368-369

🧰 Tools
🪛 LanguageTool

[grammar] ~187-~187: Use a hyphen to join words.
Context: ...at the same time as the article. In real world applications, the child might be n...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/react/guides/request-waterfalls.md` at line 187, Summary:
Hyphenate compound modifiers like "real world" to "real-world" for grammar
consistency. Fix: update the prose that mentions "<Comments>" and "<Article>" to
use "real-world applications" and any other compound modifiers (e.g., "child
might be nested far below the parent" if used as a modifier) to be hyphenated;
search for occurrences around the discussion of hoisting the comments query to
the parent and at the alternate locations noted (also applies to lines
referencing 368-369) and replace plain compounds with hyphenated forms to
maintain consistent compound-adjective styling.

Comment on lines 272 to 275
```
1. |> getFeed()
2. |> getGraphDataById()
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a language to the fenced code block.

Markdownlint warns about missing language specifier here. Consider marking it as plain text.

💡 Suggested change
-```
+```text
 1. |> getFeed()
 2.   |> getGraphDataById()
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 272-272: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/react/guides/request-waterfalls.md` around lines 272 - 275,
The fenced code block showing the waterfall steps (the lines containing
"getFeed()" and "getGraphDataById()") is missing a language tag; update that
triple-backtick block to include a language specifier (e.g., "text") so
Markdownlint stops warning and the snippet is properly annotated.

Comment on lines +143 to +168
```tsx
useMutation(() => ({
mutationFn: addTodo,
onSuccess: (data, variables, onMutateResult, context) => {
// I will fire first
},
onError: (error, variables, onMutateResult, context) => {
// I will fire first
},
onSettled: (data, error, variables, onMutateResult, context) => {
// I will fire first
},
}))

mutate(todo, {
onSuccess: (data, variables, onMutateResult, context) => {
// I will fire second!
},
onError: (error, variables, onMutateResult, context) => {
// I will fire second!
},
onSettled: (data, error, variables, onMutateResult, context) => {
// I will fire second!
},
})
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Same callback signature issue in Example6.

The callbacks here also use the incorrect onMutateResult parameter pattern.

Proposed fix
 useMutation(() => ({
   mutationFn: addTodo,
-  onSuccess: (data, variables, onMutateResult, context) => {
+  onSuccess: (data, variables, context) => {
     // I will fire first
   },
-  onError: (error, variables, onMutateResult, context) => {
+  onError: (error, variables, context) => {
     // I will fire first
   },
-  onSettled: (data, error, variables, onMutateResult, context) => {
+  onSettled: (data, error, variables, context) => {
     // I will fire first
   },
 }))

 mutate(todo, {
-  onSuccess: (data, variables, onMutateResult, context) => {
+  onSuccess: (data, variables, context) => {
     // I will fire second!
   },
-  onError: (error, variables, onMutateResult, context) => {
+  onError: (error, variables, context) => {
     // I will fire second!
   },
-  onSettled: (data, error, variables, onMutateResult, context) => {
+  onSettled: (data, error, variables, context) => {
     // I will fire second!
   },
 })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/solid/guides/mutations.md` around lines 143 - 168, The example
callbacks for useMutation and mutate use an incorrect fourth parameter name
"onMutateResult"; update all onSuccess/onError/onSettled callback signatures in
the useMutation options and in the mutate call to match the correct mutation
callback shape (three params): onSuccess(data, variables, context),
onError(error, variables, context), onSettled(dataOrUndefined, errorOrUndefined,
variables, context) — or if your API expects three params for settled, use
(data, error, context); replace any "onMutateResult" occurrences with "context"
and remove the extra parameter so the callbacks in useMutation and mutate
reference the correct symbols and ordering.

Comment on lines +173 to +190
```tsx
useMutation(() => ({
mutationFn: addTodo,
onSuccess: (data, variables, onMutateResult, context) => {
// Will be called 3 times
},
}))

const todos = ['Todo 1', 'Todo 2', 'Todo 3']
todos.forEach((todo) => {
mutate(todo, {
onSuccess: (data, variables, onMutateResult, context) => {
// Will execute only once, for the last mutation (Todo 3),
// regardless which mutation resolves first
},
})
})
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Same callback signature issue in Example7.

Proposed fix
 useMutation(() => ({
   mutationFn: addTodo,
-  onSuccess: (data, variables, onMutateResult, context) => {
+  onSuccess: (data, variables, context) => {
     // Will be called 3 times
   },
 }))

 const todos = ['Todo 1', 'Todo 2', 'Todo 3']
 todos.forEach((todo) => {
   mutate(todo, {
-    onSuccess: (data, variables, onMutateResult, context) => {
+    onSuccess: (data, variables, context) => {
       // Will execute only once, for the last mutation (Todo 3),
       // regardless which mutation resolves first
     },
   })
 })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/solid/guides/mutations.md` around lines 173 - 190, The
onSuccess callbacks in the Example7 snippet use an incorrect four-parameter
signature (data, variables, onMutateResult, context); update both the global
useMutation onSuccess and the per-call mutate onSuccess to the correct signature
used by this library (e.g., onSuccess: (data, variables, context) => { ... })
and adjust any references to the removed parameter (onMutateResult) accordingly;
specifically edit the useMutation block and the mutate(...) call that reference
addTodo, useMutation, and mutate to use (data, variables, context) so the docs
match the real API.

Comment on lines +221 to +255
```tsx
const queryClient = new QueryClient()

// Define the "addTodo" mutation
queryClient.setMutationDefaults(['addTodo'], {
mutationFn: addTodo,
onMutate: async (variables, context) => {
// Cancel current queries for the todos list
await context.client.cancelQueries({ queryKey: ['todos'] })

// Create optimistic todo
const optimisticTodo = { id: uuid(), title: variables.title }

// Add optimistic todo to todos list
context.client.setQueryData(['todos'], (old) => [...old, optimisticTodo])

// Return a result with the optimistic todo
return { optimisticTodo }
},
onSuccess: (result, variables, onMutateResult, context) => {
// Replace optimistic todo in the todos list with the result
context.client.setQueryData(['todos'], (old) =>
old.map((todo) =>
todo.id === onMutateResult.optimisticTodo.id ? result : todo,
),
)
},
onError: (error, variables, onMutateResult, context) => {
// Remove optimistic todo from the todos list
context.client.setQueryData(['todos'], (old) =>
old.filter((todo) => todo.id !== onMutateResult.optimisticTodo.id),
)
},
retry: 3,
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Same callback signature issue in Example10.

The setMutationDefaults example also uses incorrect callback signatures with onMutateResult.

Proposed fix
 queryClient.setMutationDefaults(['addTodo'], {
   mutationFn: addTodo,
-  onMutate: async (variables, context) => {
+  onMutate: async (variables) => {
     // Cancel current queries for the todos list
-    await context.client.cancelQueries({ queryKey: ['todos'] })
+    await queryClient.cancelQueries({ queryKey: ['todos'] })

     // Create optimistic todo
     const optimisticTodo = { id: uuid(), title: variables.title }

     // Add optimistic todo to todos list
-    context.client.setQueryData(['todos'], (old) => [...old, optimisticTodo])
+    queryClient.setQueryData(['todos'], (old) => [...old, optimisticTodo])

     // Return a result with the optimistic todo
     return { optimisticTodo }
   },
-  onSuccess: (result, variables, onMutateResult, context) => {
+  onSuccess: (result, variables, context) => {
     // Replace optimistic todo in the todos list with the result
-    context.client.setQueryData(['todos'], (old) =>
+    queryClient.setQueryData(['todos'], (old) =>
       old.map((todo) =>
-        todo.id === onMutateResult.optimisticTodo.id ? result : todo,
+        todo.id === context.optimisticTodo.id ? result : todo,
       ),
     )
   },
-  onError: (error, variables, onMutateResult, context) => {
+  onError: (error, variables, context) => {
     // Remove optimistic todo from the todos list
-    context.client.setQueryData(['todos'], (old) =>
-      old.filter((todo) => todo.id !== onMutateResult.optimisticTodo.id),
+    queryClient.setQueryData(['todos'], (old) =>
+      old.filter((todo) => todo.id !== context.optimisticTodo.id),
     )
   },
   retry: 3,
 })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```tsx
const queryClient = new QueryClient()
// Define the "addTodo" mutation
queryClient.setMutationDefaults(['addTodo'], {
mutationFn: addTodo,
onMutate: async (variables, context) => {
// Cancel current queries for the todos list
await context.client.cancelQueries({ queryKey: ['todos'] })
// Create optimistic todo
const optimisticTodo = { id: uuid(), title: variables.title }
// Add optimistic todo to todos list
context.client.setQueryData(['todos'], (old) => [...old, optimisticTodo])
// Return a result with the optimistic todo
return { optimisticTodo }
},
onSuccess: (result, variables, onMutateResult, context) => {
// Replace optimistic todo in the todos list with the result
context.client.setQueryData(['todos'], (old) =>
old.map((todo) =>
todo.id === onMutateResult.optimisticTodo.id ? result : todo,
),
)
},
onError: (error, variables, onMutateResult, context) => {
// Remove optimistic todo from the todos list
context.client.setQueryData(['todos'], (old) =>
old.filter((todo) => todo.id !== onMutateResult.optimisticTodo.id),
)
},
retry: 3,
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/solid/guides/mutations.md` around lines 221 - 255, The
callbacks provided to queryClient.setMutationDefaults use the wrong
signatures—onMutate currently expects (variables, context) and returns a context
named onMutateResult, while onSuccess/onError are declared with an extra
parameter; fix by making onMutate async (variables) => { await
queryClient.cancelQueries(['todos']); const optimisticTodo = { id: uuid(),
title: variables.title }; queryClient.setQueryData(['todos'], old => [...old,
optimisticTodo]); return { optimisticTodo } } and update onSuccess and onError
to use the proper signature (data, variables, context) => {
queryClient.setQueryData(['todos'], old => old.map/todo filtering using
context.optimisticTodo.id) } so they read context.optimisticTodo (replace uses
of onMutateResult and context.client with the returned context and the outer
queryClient respectively).

Comment on lines +111 to +120
```tsx
const client = new GraphQLClient(endpoint)

const todosQuery = useQuery(() => ({
queryKey: ['todos'],
queryFn: ({ signal }) => {
client.request({ document: query, signal })
},
}))
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing return statement in queryFn.

The queryFn doesn't return the promise from client.request(), so the query will resolve with undefined instead of the actual data.

Proposed fix
 const todosQuery = useQuery(() => ({
   queryKey: ['todos'],
   queryFn: ({ signal }) => {
-    client.request({ document: query, signal })
+    return client.request({ document: query, signal })
   },
 }))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/solid/guides/query-cancellation.md` around lines 111 - 120,
The queryFn passed to useQuery (in the todosQuery example) does not return the
Promise from client.request so the query resolves to undefined; update the
queryFn to return the client.request call (i.e., ensure the function passed as
queryFn returns the result of client.request({ document: query, signal })) so
useQuery receives the fetched data—look for GraphQLClient, client.request,
useQuery, queryFn and todosQuery in the snippet and add the missing return.

Comment on lines +5 to +6
- `npm install`
- `npm run start`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Incorrect script name in instructions.

The README references npm run start, but the package.json defines a dev script instead. This will cause the command to fail.

📝 Proposed fix
 - `npm install`
-- `npm run start`
+- `npm run dev`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- `npm install`
- `npm run start`
- `npm install`
- `npm run dev`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/solid/offline/README.md` around lines 5 - 6, The README references
running `npm run start` but package.json only defines the `dev` script, causing
the command to fail; update the README.md instructions to use `npm run dev` (or
add a `start` script to package.json that maps to `dev`) so the command matches
the actual script name—look for the script entries in package.json and the
command lines in README.md and make them consistent.

Comment on lines +146 to +153
function submitForm(event: SubmitEvent) {
event.preventDefault()

updateMovie.mutate({
id: props.movieId,
comment: comment(),
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Potential undefined comment when submitting.

comment() could return undefined if no local edits were made (it falls back to movieQuery.data?.movie.comment in the hook return). When mutating, if comment is undefined, the API call in api.ts line 75 will call comment.toUpperCase() which throws a TypeError.

Proposed fix
   function submitForm(event: SubmitEvent) {
     event.preventDefault()

+    const currentComment = comment()
+    if (currentComment === undefined) return
+
     updateMovie.mutate({
       id: props.movieId,
-      comment: comment(),
+      comment: currentComment,
     })
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/solid/offline/src/App.tsx` around lines 146 - 153, submitForm can
pass an undefined comment into updateMovie.mutate which triggers a TypeError in
api.ts when comment.toUpperCase() is called; change submitForm to ensure a
defined string is sent (e.g., compute const safeComment = comment() ??
movieQuery.data?.movie.comment ?? "" before calling updateMovie.mutate) or
validate and coerce comment() to a string and pass that into updateMovie.mutate
so api.ts always receives a string value; update the submitForm function (and
any hook return usage of comment()) to guarantee non-undefined input to
updateMovie.mutate.

Comment on lines +6 to +14
worker.start()

render(
() => (
<div style={{ padding: '16px' }}>
<App />
</div>
),
document.getElementById('root')!,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Race condition: worker.start() should be awaited.

worker.start() returns a Promise. Rendering the app immediately without waiting could cause initial fetch requests to bypass MSW interception if they fire before the worker is ready.

Proposed fix
-worker.start()
-
-render(
-  () => (
-    <div style={{ padding: '16px' }}>
-      <App />
-    </div>
-  ),
-  document.getElementById('root')!,
-)
+worker.start().then(() => {
+  render(
+    () => (
+      <div style={{ padding: '16px' }}>
+        <App />
+      </div>
+    ),
+    document.getElementById('root')!,
+  )
+})
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
worker.start()
render(
() => (
<div style={{ padding: '16px' }}>
<App />
</div>
),
document.getElementById('root')!,
worker.start().then(() => {
render(
() => (
<div style={{ padding: '16px' }}>
<App />
</div>
),
document.getElementById('root')!,
)
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/solid/offline/src/index.tsx` around lines 6 - 14, worker.start() is
asynchronous and currently races with initial renders; await the worker startup
before calling render so MSW is ready to intercept requests — change the flow so
you await the Promise returned by worker.start() (referencing worker.start())
and only then call render(...) to mount <App /> (referencing render and App) to
eliminate the race condition.

Comment on lines +22 to +42
const updateMovie = useMutation(() => ({
mutationKey: movieKeys.detail(movieId),
onMutate: async () => {
await queryClient.cancelQueries({ queryKey: movieKeys.detail(movieId) })
const previousData = queryClient.getQueryData<
Awaited<ReturnType<typeof api.fetchMovie>>
>(movieKeys.detail(movieId))

// remove local state so that server state is taken instead
setComment(undefined)

queryClient.setQueryData(movieKeys.detail(movieId), {
...previousData,
movie: {
...previousData?.movie,
comment: comment(),
},
})

return { previousData }
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Bug: comment() returns undefined after clearing the signal.

On line 31, setComment(undefined) clears the local comment state. Then on line 37, comment() is called to set the optimistic cache value, but it will return undefined since the signal was just cleared. The previous comment value should be captured before clearing.

Proposed fix
     onMutate: async () => {
       await queryClient.cancelQueries({ queryKey: movieKeys.detail(movieId) })
       const previousData = queryClient.getQueryData<
         Awaited<ReturnType<typeof api.fetchMovie>>
       >(movieKeys.detail(movieId))

+      // Capture the current comment before clearing
+      const newComment = comment()
+
       // remove local state so that server state is taken instead
       setComment(undefined)

       queryClient.setQueryData(movieKeys.detail(movieId), {
         ...previousData,
         movie: {
           ...previousData?.movie,
-          comment: comment(),
+          comment: newComment,
         },
       })

       return { previousData }
     },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const updateMovie = useMutation(() => ({
mutationKey: movieKeys.detail(movieId),
onMutate: async () => {
await queryClient.cancelQueries({ queryKey: movieKeys.detail(movieId) })
const previousData = queryClient.getQueryData<
Awaited<ReturnType<typeof api.fetchMovie>>
>(movieKeys.detail(movieId))
// remove local state so that server state is taken instead
setComment(undefined)
queryClient.setQueryData(movieKeys.detail(movieId), {
...previousData,
movie: {
...previousData?.movie,
comment: comment(),
},
})
return { previousData }
},
const updateMovie = useMutation(() => ({
mutationKey: movieKeys.detail(movieId),
onMutate: async () => {
await queryClient.cancelQueries({ queryKey: movieKeys.detail(movieId) })
const previousData = queryClient.getQueryData<
Awaited<ReturnType<typeof api.fetchMovie>>
>(movieKeys.detail(movieId))
// Capture the current comment before clearing
const newComment = comment()
// remove local state so that server state is taken instead
setComment(undefined)
queryClient.setQueryData(movieKeys.detail(movieId), {
...previousData,
movie: {
...previousData?.movie,
comment: newComment,
},
})
return { previousData }
},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/solid/offline/src/movies.ts` around lines 22 - 42, In updateMovie's
onMutate handler capture the current comment value into a local variable before
calling setComment(undefined) so the optimistic update uses the preserved value;
specifically, inside the onMutate for updateMovie (which uses
movieKeys.detail(movieId)) read comment() into e.g. previousComment, then call
setComment(undefined), and pass previousComment into
queryClient.setQueryData(...) when setting movie.comment and return
previousComment in the mutation context so rollback can restore it if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments