-
-
Notifications
You must be signed in to change notification settings - Fork 3
FetchQueries and FetchInfiniteQueries #89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
52f86f8
580d2cf
f14fce0
0a19011
90c4236
91ac7db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "mobx-tanstack-query": minor | ||
| --- | ||
|
|
||
| added fetch queries new features (FetchQuery, createFetchQuery) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -21,12 +21,15 @@ jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Checkout tree | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Set-up Node.js | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/setup-node@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check-latest: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node-version-file: .nvmrc | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| registry-url: https://registry.npmjs.org | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - run: corepack enable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - run: pnpm i | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -43,15 +46,16 @@ jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "last_tag=$tag" >> $GITHUB_OUTPUT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - run: npm install -g npm@latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Create Release Pull Request | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: changesets/action@v1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue-on-error: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: pub-or-release-pr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| version: pnpm changeset version | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| publish: pnpm pub | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createGithubReleases: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CI: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GITHUB_TOKEN: ${{ github.token }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+49
to
61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: sed -n '1,140p' .github/workflows/version-or-publish.yml && printf '\n---\n' && rg -n "NODE_AUTH_TOKEN|NPM_TOKEN|registry-url|changesets/action|pnpm pub" .github/workflows . -g '!**/node_modules/**'Repository: js2me/mobx-tanstack-query Length of output: 2586 🏁 Script executed: sed -n '1,220p' package.json && printf '\n---\n' && fd -a 'config.json' .changeset .github . && printf '\n---\n' && rg -n "\"pub\"|changesets|publishConfig|npmrc|NODE_AUTH_TOKEN|NPM_TOKEN" package.json .changeset .github -g '!**/node_modules/**'Repository: js2me/mobx-tanstack-query Length of output: 3817 🌐 Web query:
💡 Result: To authenticate and publish an npm package using GitHub Actions, you use the actions/setup-node action to configure a local.npmrc file with your registry information and authentication token [1][2]. For classic token-based authentication: 1. Create a repository secret (e.g., NPM_TOKEN) in your GitHub repository containing your npm authentication token [1][2]. 2. In your workflow YAML, use actions/setup-node with the registry-url input set to the registry (e.g., https://registry.npmjs.org/) [1][2]. 3. Provide the secret to the action via the NODE_AUTH_TOKEN environment variable in the step that runs npm publish [1][2]. Example workflow configuration: - uses: actions/setup-node@v4 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org' - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} When the registry-url is set, actions/setup-node automatically creates a temporary.npmrc file that references the NODE_AUTH_TOKEN variable, allowing npm to authenticate during the publish process [1][2]. Note on Trusted Publishing (OIDC): Modern workflows can use npm's Trusted Publisher (OIDC) feature to publish without long-lived tokens [3]. If you are using OIDC, be aware that setting registry-url in actions/setup-node historically adds an _authToken placeholder to the.npmrc file [4]. While this is the standard setup for token-based auth, some users have reported issues with this configuration in OIDC-only environments [4]. Always ensure your workflow permissions include id-token: write when using OIDC [1][2]. Citations:
Add 🔧 Proposed fix env:
CI: true
GITHUB_TOKEN: ${{ github.token }}
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}📝 Committable suggestion
Suggested change
🧰 Tools🪛 zizmor (1.26.1)[warning] 49-49: ad-hoc installation of packages (adhoc-packages): installs a package outside of a lockfile (adhoc-packages) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,67 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # FetchInfiniteQuery | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| A [`FetchQuery`](/api/FetchQuery) for paginated data — same declarative `params` API, but with built-in page navigation. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Like [`FetchQuery`](/api/FetchQuery), it auto-generates `queryKey` from `params` and handles the HTTP request for you. The difference is that `params` receives a `pageParam` argument, and you control pagination via `getNextPageParam`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| **All properties and methods** (`data`, `isLoading`, `error`, `fetchNextPage`, `hasNextPage`, etc.) are inherited from [`InfiniteQuery`](/api/InfiniteQuery). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [Reference to source code](/src/fetch-infinite-query.ts) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Usage | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```ts | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const starsQuery = new FetchInfiniteQuery({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| queryClient, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| params: ({ pageParam }) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
cubic-dev-ai[bot] marked this conversation as resolved.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path: '/stars', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| query: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| count: 20, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| page: pageParam, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| initialPageParam: 1, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getNextPageParam: (lastPage, _, lastPageParam) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return lastPage.length ? lastPageParam + 1 : null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Manual control with `start()` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Create a `FetchInfiniteQuery` without `params` (disabled by default), then fetch manually: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```ts | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const starsQuery = new FetchInfiniteQuery({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| queryClient, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| initialPageParam: 1, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getNextPageParam: (lastPage, _, lastPageParam) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return lastPage.length ? lastPageParam + 1 : null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const result = await starsQuery.start({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| params: { path: '/stars', query: { count: 20 } }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### How it works | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1. `params` is a function that receives `{ pageParam }` — the current page parameter (starts at `initialPageParam`) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 2. Each page request uses the same `params` logic with a different `pageParam` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 3. After each page loads, `getNextPageParam` determines the next page parameter — return `null` to indicate no more pages | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 4. `data` is an array of all fetched pages, and `fetchNextPage()` triggers the next request | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Example: cursor-based pagination | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```ts | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const commentsQuery = new FetchInfiniteQuery({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| queryClient, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| params: ({ pageParam }) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path: '/comments', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| query: { cursor: pageParam }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| initialPageParam: undefined as string | undefined, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getNextPageParam: (lastPage) => lastPage.nextCursor ?? null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+30
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Line 53 states " 📝 Proposed fix-4. `data` is an array of all fetched pages, and `fetchNextPage()` triggers the next request
+4. `data` is an `InfiniteData` object whose `.pages` array holds all fetched pages, and `fetchNextPage()` triggers the next request📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| # FetchQuery | ||
|
|
||
| A [`Query`](/api/Query) that makes HTTP requests for you — no need to write `queryFn` or `queryKey` manually. | ||
|
|
||
| Instead of describing **how** to fetch data, you describe **what** to fetch using `params`: | ||
|
|
||
| ```ts | ||
| // Query — you write the fetch logic yourself | ||
| new Query({ | ||
| queryClient, | ||
| queryKey: ['/pets'], | ||
| queryFn: () => fetch('/pets').then(r => r.json()), | ||
| }) | ||
|
|
||
| // FetchQuery — just describe the request | ||
| new FetchQuery({ | ||
| queryClient, | ||
| params: { path: '/pets' }, | ||
| }) | ||
| ``` | ||
|
|
||
| `FetchQuery` auto-generates `queryKey` from your `params`, so the cache stays consistent automatically. | ||
|
|
||
| **All properties and methods** (`data`, `isLoading`, `error`, `refetch`, etc.) are inherited from [`Query`](/api/Query). | ||
|
|
||
| [Reference to source code](/src/fetch-query.ts) | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Basic GET request | ||
|
|
||
| ```ts | ||
| const petsQuery = new FetchQuery({ | ||
| queryClient, | ||
| params: { | ||
| path: '/pets', | ||
| }, | ||
| }); | ||
|
|
||
| console.log(petsQuery.data, petsQuery.isLoading); | ||
| ``` | ||
|
|
||
| ### Dynamic params | ||
|
|
||
| `params` can be a function — when MobX observables inside it change, the query automatically refetches with new parameters. Return a falsy value to disable the query. | ||
|
|
||
| ```ts | ||
| const petId = observable.box<string>(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '--- docs/api/FetchQuery.md (around the cited lines) ---\n'
sed -n '1,140p' docs/api/FetchQuery.md | cat -n
printf '\n--- package references to mobx ---\n'
rg -n '"mobx"|observable\.box|FetchQuery' package.json . -g 'package.json' -g '*.md' -g '*.ts' -g '*.tsx' -g '*.js' -g '*.jsx'Repository: js2me/mobx-tanstack-query Length of output: 254 🌐 Web query:
💡 Result: In MobX, observable.box(value, options?) requires an initial value to be provided [1][2]. While earlier versions or certain type definitions may have permitted omitting the argument, providing an initial value is standard practice to ensure type safety and prevent runtime errors [3]. If you attempt to use observable.box without an argument, it may lead to TypeScript errors or runtime issues when you subsequently call.get on the empty box [3]. To correctly initialize a box with no specific value, you should explicitly pass undefined or null: const myBox = observable.box(undefined); // Correct initialization [3] myBox.set("new value"); // Safely update later The observable.box API is used to create an observable reference to a value, primarily for primitive values that are not owned by an object [2]. Once created, you interact with the value using the.get and.set(newValue) methods [1][2]. Citations:
Initialize the MobX box with a value. 🤖 Prompt for AI Agents |
||
|
|
||
| const petQuery = new FetchQuery({ | ||
| queryClient, | ||
| params: () => petId.get() | ||
| ? { path: `/pets/${petId.get()}` } | ||
| : null, // query is disabled while petId is empty | ||
| }); | ||
| ``` | ||
|
|
||
| ### POST request with body | ||
|
|
||
| ```ts | ||
| const createPetQuery = new FetchQuery({ | ||
| queryClient, | ||
| params: () => ({ | ||
| path: '/pets', | ||
| method: 'POST', | ||
| body: { name: 'Fluffy', type: 'cat' }, | ||
| }), | ||
| }); | ||
| ``` | ||
|
|
||
| ### Full fetch configuration | ||
|
|
||
| ```ts | ||
| const petQuery = new FetchQuery({ | ||
| queryClient, | ||
| params: { | ||
| baseUrl: 'https://api.example.com', | ||
| path: '/pets', | ||
| query: { limit: 10, sort: 'name' }, | ||
| method: 'GET', | ||
| headers: { 'X-Custom-Header': 'value' }, | ||
| notFoundAsNull: true, | ||
| }, | ||
| }); | ||
| ``` | ||
|
|
||
| ## `FetchQueryParams` | ||
|
|
||
| - `path: string` — **Required.** The URL path for the request | ||
| - `baseUrl?: string` — Base URL prepended to `path`. Can also be set globally via [`QueryClient.fetchQueries`](/api/QueryClient#fetchqueries) | ||
| - `query?: Record<string, string | number | boolean | null | undefined>` — Query parameters to be serialized and appended to the URL | ||
| - `method?: string` — HTTP method. Defaults to `"GET"` (or `"POST"` when `body` is provided) | ||
| - `headers?: Record<string>` — Request headers. Merged with global headers from `QueryClient.fetchQueries` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Prompt for AI agents |
||
| - `body?: BodyInit | Record<string, unknown>` — Request body. Objects are JSON-serialized with `Content-Type: application/json`; native `BodyInit` (Blob, FormData, etc.) is passed through as-is | ||
|
Comment on lines
+93
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Show the relevant section with line numbers and a bit of surrounding context.
sed -n '60,95p' docs/api/FetchQuery.md | cat -n
# Also locate any similar Record typings elsewhere in the docs to compare conventions.
rg -n "Record<string" docs -SRepository: js2me/mobx-tanstack-query Length of output: 3140 Use complete 🤖 Prompt for AI Agents |
||
| - `request?: Partial<RequestInit>` — Additional `RequestInit` options (except `signal`, `method`, `headers`, `body`) | ||
| - `notFoundAsNull?: boolean` — If `true`, a 404 response returns `null` instead of throwing | ||
| - `responseType?: ResponseType` — Method to read the response body (e.g. `"json"`, `"text"`, `"blob"`). Defaults to `"json"` | ||
| - `transformResponse?: TransformResponseFn` — Custom function to transform the `Response` object before data is returned | ||
| - `throwOnError?: boolean` — Whether to throw the raw `Response` on non-ok status. Defaults to `true` | ||
| - `meta?: QueryMeta` — Metadata attached to the query | ||
|
|
||
| ## Manual control with `start()` | ||
|
|
||
| Create a `FetchQuery` without `params` (disabled by default), then fetch manually: | ||
|
|
||
| ```ts | ||
| const petQuery = new FetchQuery({ | ||
| queryClient, | ||
| // no params — query is disabled | ||
| }); | ||
|
|
||
| const result = await petQuery.start({ | ||
| params: { path: '/pets/123' }, | ||
| }); | ||
|
|
||
| console.log(result.data); | ||
| ``` | ||
|
|
||
| ## Request behavior | ||
|
|
||
| - Per-request `params` are **merged** with global defaults from [`QueryClient.fetchQueries`](/api/QueryClient#fetchqueries) (per-request values take precedence) | ||
| - The full URL is built as `baseUrl + path` with `query` params serialized and appended | ||
| - `queryKey` is auto-generated from `params` — you never set it manually | ||
|
|
||
| ## Recommendations | ||
|
|
||
| ### Use `QueryClient.fetchQueries` for global configuration | ||
|
|
||
| Instead of repeating `baseUrl`, `headers`, and other options in every `FetchQuery`, set them once on the `QueryClient`: | ||
|
|
||
| ```ts | ||
| const queryClient = new QueryClient({ | ||
| fetchQueries: { | ||
| baseUrl: 'https://api.example.com', | ||
| headers: { | ||
| Authorization: 'Bearer my-token', | ||
| }, | ||
| throwOnError: true, | ||
| timeout: 30_000, | ||
| }, | ||
| }); | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -28,6 +28,7 @@ interface QueryClientConfig { | |||||
| mutations: MobxMutatonFeatures; | ||||||
| }; | ||||||
| hooks?: QueryClientHooks; | ||||||
| fetchQueries?: FetchQueriesOptions; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
|
|
@@ -92,6 +93,38 @@ Entity lifecycle events. Available hooks: | |||||
| | onInfiniteQueryDestroy | Triggered when a [`InfiniteQuery`](/api/InfiniteQuery) is destroyed | | ||||||
| | onMutationDestroy | Triggered when a [`Mutation`](/api/Mutation) is destroyed | | ||||||
|
|
||||||
| ### `fetchQueries` | ||||||
|
|
||||||
| Global configuration for [`FetchQuery`](/api/FetchQuery) and [`FetchInfiniteQuery`](/api/FetchInfiniteQuery). These defaults are merged with per-request `params` in every fetch query. | ||||||
|
|
||||||
| - `baseUrl?: string` — Base URL prepended to every `path` | ||||||
| - `headers?: Record<string>` — Default headers merged with per-request headers | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Inspect the documented line and nearby context
sed -n '85,120p' docs/api/QueryClient.md
# Search for the same header type pattern elsewhere in docs and source
rg -n "Record<string>" docs src . --glob '!**/node_modules/**' || true
# Find the runtime/query option contract that this doc refers to
rg -n "headers\\?:|Default headers|per-request headers|headers" docs src --glob '!**/node_modules/**' || trueRepository: js2me/mobx-tanstack-query Length of output: 7341 Use a complete header type here.
🤖 Prompt for AI AgentsThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Prompt for AI agents
Suggested change
|
||||||
| - `customFetch?: typeof globalThis.fetch` — Custom fetch implementation (useful for testing or non-browser environments) | ||||||
| - `transformResponse?: TransformResponseFn` — Global response transformation function | ||||||
| - `throwOnError?: boolean` — Whether to throw the raw `Response` on non-ok status. Defaults to `true` | ||||||
| - `timeout?: number` — Request timeout in milliseconds | ||||||
| - `credentials?: RequestCredentials` — Credentials mode for requests (e.g. `"include"`, `"same-origin"`) | ||||||
| - `mode?: RequestMode` — Request mode (e.g. `"cors"`, `"no-cors"`) | ||||||
| - `meta?: QueryMeta` — Default metadata attached to fetch queries | ||||||
|
|
||||||
| Example: | ||||||
|
|
||||||
| ```ts | ||||||
| import { QueryClient } from "mobx-tanstack-query"; | ||||||
|
|
||||||
| const queryClient = new QueryClient({ | ||||||
| fetchQueries: { | ||||||
| baseUrl: "https://api.example.com", | ||||||
| headers: { | ||||||
| Authorization: "Bearer __TOKEN__", | ||||||
| }, | ||||||
| throwOnError: true, | ||||||
| timeout: 30_000, | ||||||
| credentials: "include", | ||||||
| }, | ||||||
| }); | ||||||
| ``` | ||||||
|
|
||||||
| ## Inheritance | ||||||
|
|
||||||
| `QueryClient` inherits all methods and properties from [QueryClient](https://tanstack.com/query/v5/docs/reference/QueryClient), including: | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,18 @@ | ||
| # Other | ||
|
|
||
| ## `InferQuery`, `InferMutation`, `InferInfiniteQuery` types | ||
| ## `InferQuery`, `InferMutation`, `InferInfiniteQuery`, `InferFetchQuery`, `InferFetchInfiniteQuery` types | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: The types Prompt for AI agents |
||
|
|
||
| This types are needed to infer some other types from mutations\configs. | ||
|
|
||
| ```ts | ||
| type MyData = InferMutation<typeof myMutation, "data">; | ||
| type MyVariables = InferMutation<typeof myMutation, "variables">; | ||
| type MyConfig = InferMutation<typeof myMutation, "config">; | ||
| type MyFetchData = InferFetchQuery<typeof myFetchQuery, "data">; | ||
| type MyFetchConfig = InferFetchQuery<typeof myFetchQuery, "config">; | ||
| ``` | ||
|
|
||
| ## `QueryConfigFromFn`, `MutationConfigFromFn`, `InfiniteQueryConfigFromFn` | ||
| ## `QueryConfigFromFn`, `MutationConfigFromFn`, `InfiniteQueryConfigFromFn`, `FetchQueryConfigFromFn`, `FetchInfiniteQueryConfigFromFn` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: The types Prompt for AI agents-## This types are needed to create configuration types from your functions of your http client |
||
|
|
||
| This types are needed to create configuration types from your functions of your http client | ||
|
|
||
|
|
@@ -24,7 +26,7 @@ type Config = MutationConfigFromFn<typeof myApi.createApple> | |
|
|
||
| ## `using` keyword | ||
|
|
||
| `Query`, `InfiniteQuery`, `Mutation` supports out-of-box [`using` keyword](https://github.com/tc39/proposal-explicit-resource-management). | ||
| `Query`, `InfiniteQuery`, `Mutation`, `FetchQuery`, `FetchInfiniteQuery` supports out-of-box [`using` keyword](https://github.com/tc39/proposal-explicit-resource-management). | ||
|
|
||
| In your project you need to install babel plugin [`@babel/plugin-proposal-explicit-resource-management`](https://www.npmjs.com/package/@babel/plugin-proposal-explicit-resource-management) to add this support. | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: The
NPM_TOKENandNPM_AUTH_TOKENenvironment variables were removed from thechangesets/actionstep, but no alternative npm authentication was provided. Thesetup-nodestep addsregistry-urlbut does not setNODE_AUTH_TOKEN, so no auth token is written to.npmrc. Thechangesets/actionrelies on theNPM_TOKENenv var to automatically configure npm authentication for publishing. Without it, the publish step will fail when attempting to publish to the npm registry. Either restore theNPM_TOKENsecret as an env var on the action step, or setNODE_AUTH_TOKENwith${{ secrets.NPM_TOKEN }}if relying onsetup-nodeauth.Prompt for AI agents