Skip to content

Commit 73207cc

Browse files
committed
feat: add resultObservable
1 parent b03ca17 commit 73207cc

9 files changed

Lines changed: 1418 additions & 1510 deletions

File tree

.changeset/curly-forks-divide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"mobx-tanstack-query": minor
3+
---
4+
5+
added `resultObservable` query and mutation features

docs/api/Mutation.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,27 @@ const mutation = createMutation(queryClient, () => ({
152152
// no reactions and subscriptions will be created
153153
```
154154

155+
### `resultObservable` <Badge type="tip">MutationFeature</Badge>
156+
157+
[_Can be specified using `QueryClient`_](https://js2me.github.io/mobx-tanstack-query/api/QueryClient.html#mutationfeatures)
158+
159+
Chooses how MobX observes the mutation **`result`** property (the `MutationObserverResult`). The library applies `annotation.observable()` from [`yummies/mobx`](https://github.com/js2me/yummies). [`Query`](https://js2me.github.io/mobx-tanstack-query/api/Query.html#resultobservable-queryfeature) stores the payload on a private `_result` and exposes TanStack fields via getters; **`Mutation` decorates the public `result` field directly** — there is no `_result`.
160+
161+
- **Default** — when omitted, behaviour matches **`'deep'`** (deep observability for plain objects and arrays in the result).
162+
- **`'ref'`** — only the reference to the result object is tracked; reactions run when the whole result is replaced, not when nested fields change in place.
163+
- **`'shallow'`** / **`'struct'`** — shallow or structural comparison for nested properties.
164+
- **`false`** — do not decorate `result` (rare; you lose automatic MobX tracking for the result blob).
165+
166+
Example:
167+
168+
```ts
169+
const mutation = new Mutation({
170+
queryClient,
171+
resultObservable: 'ref',
172+
mutationFn: async (name: string) => api.createPet(name),
173+
});
174+
```
175+
155176
### `destroy()` method
156177

157178
This method is necessary to kill all reactions and subscriptions that are created during the creation of an instance of the `Mutation` class
@@ -177,3 +198,7 @@ Reset current mutation
177198
### property `result` <Badge type="info" text="observable.deep" />
178199

179200
Mutation result (The same as returns the [`useMutation` hook](https://tanstack.com/query/latest/docs/framework/react/reference/useMutation))
201+
202+
::: info `observable.deep` is configurable
203+
The badge reflects the **default**: the public `result` property is decorated as deep observable (unlike `Query`, which uses a private `_result` behind getters). Change the MobX flavour with [`resultObservable`](#resultobservable-mutationfeature) (`ref`, `shallow`, `struct`, `true`, or `false`).
204+
:::

docs/api/Query.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,10 @@ This field is needed for `enableOnDemand` option
295295

296296
Query original result (The same as returns the [`useQuery` hook](https://tanstack.com/query/latest/docs/framework/react/reference/useQuery))
297297

298+
::: info `observable.deep` is configurable
299+
The badge reflects the **default**: the internal `_result` field is decorated as deep observable. You can change the MobX flavour (`ref`, `shallow`, `struct`, `true`, or `false`) with the [`resultObservable`](#resultobservable-queryfeature) query feature.
300+
:::
301+
298302
### `setData(updater, options)`
299303

300304
Set data for current query (Uses [queryClient.setQueryData](https://tanstack.com/query/latest/docs/reference/QueryClient#queryclientsetquerydata))
@@ -749,6 +753,28 @@ const query = new Query({
749753
})
750754
```
751755

756+
### `resultObservable` <Badge type="tip">QueryFeature</Badge>
757+
758+
[_Can be specified using `QueryClient`_](https://js2me.github.io/mobx-tanstack-query/api/QueryClient.html#queryfeatures)
759+
760+
Chooses how MobX observes the internal TanStack Query result object (`_result`). The library applies [`annotation.observable()`](https://github.com/js2me/yummies) from `yummies/mobx`, so this maps directly to MobX flavours: `ref`, `deep`, `shallow`, `struct`, or `true` / `false`.
761+
762+
- **Default** — when omitted, behaviour matches **`'deep'`** (deep observability for plain objects and arrays in the result).
763+
- **`'ref'`** — only the reference to the result object is tracked; use when the observer should react when the whole result is replaced, not when nested fields change in place.
764+
- **`'shallow'`** / **`'struct'`** — shallow or structural comparison for nested properties.
765+
- **`false`** — do not decorate `_result` with an observable annotation (rare; you lose automatic MobX tracking for the result blob).
766+
767+
Example:
768+
769+
```ts
770+
const query = new Query({
771+
queryClient,
772+
resultObservable: 'ref',
773+
queryKey: ['pets'],
774+
queryFn: async () => api.fetchPets(),
775+
});
776+
```
777+
752778
## Recommendations
753779

754780
### Don't forget about `abortSignal`s or `lazy` option

package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,31 +50,31 @@
5050
},
5151
"dependencies": {
5252
"linked-abort-controller": "^1.1.1",
53-
"yummies": "^7.12.0"
53+
"yummies": "^7.16.2"
5454
},
5555
"devDependencies": {
56-
"@biomejs/biome": "^2.4.10",
56+
"@biomejs/biome": "^2.4.11",
5757
"@changesets/changelog-github": "^0.6.0",
5858
"@changesets/cli": "^2.30.0",
5959
"@testing-library/react": "^16.3.2",
6060
"@types/lodash-es": "^4.17.12",
61-
"@types/node": "^20.19.37",
61+
"@types/node": "^20.19.39",
6262
"@types/react": "^18.3.28",
6363
"@vitejs/plugin-react-swc": "^4.3.0",
64-
"@vitest/coverage-istanbul": "^4.1.2",
64+
"@vitest/coverage-istanbul": "^4.1.4",
6565
"commitfmt": "^1.0.4",
6666
"js2me-biome-config": "^1.1.0",
67-
"jsdom": "^29.0.1",
67+
"jsdom": "^29.0.2",
6868
"lefthook": "^1.13.6",
6969
"nodemon": "^3.1.14",
7070
"rimraf": "^6.1.3",
71-
"sborshik": "^3.0.0",
71+
"sborshik": "^3.0.7",
7272
"terser": "^5.46.1",
7373
"tsx": "^4.21.0",
7474
"typescript": "^6.0.2",
75-
"vite": "^8.0.3",
75+
"vite": "^8.0.8",
7676
"vite-plugin-dts": "^4.5.4",
77-
"vitest": "^4.1.2"
77+
"vitest": "^4.1.4"
7878
},
7979
"packageManager": "pnpm@9.5.0+sha512.140036830124618d624a2187b50d04289d5a087f326c9edfc0ccd733d76c4f52c3a313d4fc148794a2a9d81553016004e6742e8cf850670268a7387fc220c903"
8080
}

0 commit comments

Comments
 (0)