Repository: tannerlinsley/react-query (ts)

Issue:
Paused Queries/Mutations are not persisted 
### Describe the bug

I'm fairly new to React query and first of all I want to appreciate sharing such a cool library with the community.
I'm trying to make use of new offline capabilities introduced in v4. I'm facing some problems regarding queries/mutations' dehydration in localStorage which is reproduced [here](https://codesandbox.io/s/usemutation-demo-forked-fluu13). If I set my connection to offline (using React query's built-in offline toggle), I expect the queries/mutations that are now in `paused` state to be persisted in local storage so I'll not lose them the user closes the window and then goes online. But in my code, the localStorage item is not created at all.  

I tried updating an official demo to use the latest version of react query. The result is available [here](https://codesandbox.io/s/tannerlinsley-react-query-forked-5x7482). This time the localStorage is created but is not populated with paused queries when I go offline. 

- Regarding my first case, the localStorage item is not even created. I suspect the storage is initialised only when `useQuery` is involved and in my sample, I only used mutations.
- in my second sample, I believe the correct behaviour should be to have the paused queries in localStorage with a maximum of 1 second delay (based on what I read about `createWebStoragePersister`).

I have tried to use `<PersistQueryClientProvider>` as well as `persistQueryClient` method with `<QueryClientProvider>`. Both led to the same result.

Of course, this might not be a bug and I might have misconfigured the library and in that case, I'd greatly appreciate if you let me know about the correct way.

### Your minimal, reproducible example

https://codesandbox.io/s/usemutation-demo-forked-fluu13

### Steps to reproduce

- Open the sample
- Go offline using react query's dev tools toggle
- Make a query/mutation and watch `REACT_QUERY_OFFLINE_CACHE` localStorage changes

### Expected behavior

When using `createWebStoragePersister` as the persister, React Query should dehydrate mutations/queries in paused state every 1 second.

### How often does this bug happen?

_No response_

### Screenshots or Videos

_No response_

### Platform

- OS: macOS
- Browser: Chrome
- Version: 99.0.4844.83

### react-query version

4.0.0-alpha.23

### TypeScript version

4.1.3

### Additional context

_No response_

Pull request description:
fix(persistQueryClient): add a failing test for persisting mutations
fixes #3460 

Patch:
diff --git a/.eslintrc b/.eslintrc
index a39b84e27..69e002d7d 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -16,6 +16,7 @@
     "sourceType": "module"
   },
   "rules": {
+    "react/jsx-key": ["error", { "checkFragmentShorthand": true }],
     "@typescript-eslint/ban-types": "off",
     "@typescript-eslint/ban-ts-comment": "off",
     "@typescript-eslint/explicit-module-boundary-types": "off",
diff --git a/docs/src/pages/comparison.md b/docs/src/pages/comparison.md
index 439d3b13c..b12b7e8ec 100644
--- a/docs/src/pages/comparison.md
+++ b/docs/src/pages/comparison.md
@@ -1,6 +1,6 @@
 ---
 id: comparison
-title: Comparison | React Query vs SWR vs Apollo vs RTK Query
+title: Comparison | React Query vs SWR vs Apollo vs RTK Query vs React Router
 ---
 
 > This comparison table strives to be as accurate and as unbiased as possible. If you use any of these libraries and feel the information could be improved, feel free to suggest changes (with notes or evidence of claims) using the "Edit this page on Github" link at the bottom of this page.
@@ -12,53 +12,54 @@ Feature/Capability Key:
 - 🔶 Supported and documented, but requires extra user-code to implement
 - 🛑 Not officially supported or documented.
 
-|                                                    | React Query                              | SWR [_(Website)_][swr]      | Apollo Client [_(Website)_][apollo]   | RTK-Query [_(Website)_][rtk-query]   |
-| -------------------------------------------------- | ---------------------------------------- | --------------------------- | ------------------------------------- | ------------------------------------ |
-| Github Repo / Stars                                | [![][stars-react-query]][gh-react-query] | [![][stars-swr]][gh-swr]    | [![][stars-apollo]][gh-apollo]        | [![][stars-rtk-query]][gh-rtk-query] |
-| Platform Requirements                              | React                                    | React                       | React, GraphQL                        | Redux                                |
-| Their Comparison                                   |                                          | (none)                      | (none)                                | [Comparison][rtk-query-comparison]   |
-| Supported Query Syntax                             | Promise, REST, GraphQL                   | Promise, REST, GraphQL      | GraphQL                               | Promise, REST, GraphQL               |
-| Supported Frameworks                               | React                                    | React                       | React + Others                        | Any                                  |
-| Supported Query Keys                               | JSON                                     | JSON                        | GraphQL Query                         | JSON                                 |
-| Query Key Change Detection                         | Deep Compare (Stable Serialization)      | Shallow Compare             | Deep Compare (Unstable Serialization) | Referential Equality (===)           |
-| Query Data Change Detection                        | Deep Comparison + Structural Sharing     | Deep Compare (via `dequal`) | Deep Compare (Unstable Serialization) | Referential Equality (===)           |
-| Query Data Memoization Level                       | Query + Structural Sharing               | Query                       | Query + Entity + Structural Sharing   | Query                                |
-| Bundle Size<sup>8</sup>                            | [![][bp-react-query]][bpl-react-query]   | [![][bp-swr]][bpl-swr]      | [![][bp-apollo]][bpl-apollo]          | [![][bp-rtk-query]][bpl-rtk-query]   |
-| API Definition                                     | On-Use, Declarative                      | On-Use                      | GraphQL Schema                        | Declarative                          |
-| Queries                                            | ✅                                       | ✅                          | ✅                                    | ✅                                   |
-| Caching                                            | ✅                                       | ✅                          | ✅                                    | ✅                                   |
-| Devtools                                           | ✅                                       | 🟡                          | ✅                                    | ✅                                   |
-| Polling/Intervals                                  | ✅                                       | ✅                          | ✅                                    | ✅                                   |
-| Parallel Queries                                   | ✅                                       | ✅                          | ✅                                    | ✅                                   |
-| Dependent Queries                                  | ✅                                       | ✅                          | ✅                                    | ✅                                   |
-| Paginated Queries                                  | ✅                                       | ✅                          | ✅                                    | ✅                                   |
-| Infinite Queries                                   | ✅                                       | ✅                          | ✅                                    | 🛑                                   |
-| Bi-directional Infinite Queries                    | ✅                                       | 🔶                          | 🔶                                    | 🛑                                   |
-| Infinite Query Refetching                          | ✅                                       | ✅                          | 🛑                                    | 🛑                                   |
-| Lagged Query Data<sup>1</sup>                      | ✅                                       | 🔶                          | 🛑                                    | ✅                                   |
-| Selectors                                          | ✅                                       | 🛑                          | ✅                                    | ✅                                   |
-| Initial Data                                       | ✅                                       | ✅                          | ✅                                    | ✅                                   |
-| Scroll Recovery                                    | ✅                                       | ✅                          | ✅                                    | ✅                                   |
-| Cache Manipulation                                 | ✅                                       | ✅                          | ✅                                    | ✅                                   |
-| Outdated Query Dismissal                           | ✅                                       | ✅                          | ✅                                    | ✅                                   |
-| Render Batching & Optimization<sup>2</sup>         | ✅                                       | 🛑                          | 🛑                                    | ✅                                   |
-| Auto Garbage Collection                            | ✅                                       | 🛑                          | 🛑                                    | ✅                                   |
-| Mutation Hooks                                     | ✅                                       | 🟡                          | ✅                                    | ✅                                   |
-| Offline Mutation Support                           | ✅                                       | 🛑                          | 🟡                                    | 🛑                                   |
-| Prefetching APIs                                   | ✅                                       | 🔶                          | ✅                                    | ✅                                   |
-| Query Cancellation                                 | ✅                                       | 🛑                          | 🛑                                    | 🛑                                   |
-| Partial Query Matching<sup>3</sup>                 | ✅                                       | 🛑                          | 🛑                                    | ✅                                   |
-| Stale While Revalidate                             | ✅                                       | ✅                          | ✅                                    | ✅                                   |
-| Stale Time Configuration<sup>7</sup>               | ✅                                       | 🛑                          | 🛑                                    | ✅                                   |
-| Pre-usage Query/Mutation Configuration<sup>4</sup> | ✅                                       | 🛑                          | 🛑                                    | ✅                                   |
-| Window Focus Refetching                            | ✅                                       | ✅                          | 🛑                                    | 🔶                                   |
-| Network Status Refetching                          | ✅                                       | ✅                          | ✅                                    | 🔶                                   |
-| General Cache Dehydration/Rehydration              | ✅                                       | 🛑                          | ✅                                    | ✅                                   |
-| Offline Caching                                    | ✅ (Experimental)                        | 🛑                          | ✅                                    | 🔶                                   |
-| React Suspense (Experimental)                      | ✅                                       | ✅                          | 🛑                                    | 🛑                                   |
-| Abstracted/Agnostic Core                           | ✅                                       | 🛑                          | ✅                                    | ✅                                   |
-| Automatic Refetch after Mutation<sup>5</sup>       | 🔶                                       | 🔶                          | ✅                                    | ✅                                   |
-| Normalized Caching<sup>6</sup>                     | 🛑                                       | 🛑                          | ✅                                    | 🛑                                   |
+|                                                    | React Query                              | SWR [_(Website)_][swr]      | Apollo Client [_(Website)_][apollo]        | RTK-Query [_(Website)_][rtk-query]   | React Router [_(Website)_][react-router]                                  |
+| -------------------------------------------------- | ---------------------------------------- | --------------------------- | ------------------------------------------ | ------------------------------------ | ------------------------------------------------------------------------- |
+| Github Repo / Stars                                | [![][stars-react-query]][gh-react-query] | [![][stars-swr]][gh-swr]    | [![][stars-apollo]][gh-apollo]             | [![][stars-rtk-query]][gh-rtk-query] | [![][stars-react-router]][gh-react-router]                                |
+| Platform Requirements                              | React                                    | React                       | React, GraphQL                             | Redux                                | React                                                                     |
+| Their Comparison                                   |                                          | (none)                      | (none)                                     | [Comparison][rtk-query-comparison]   | [Comparison][react-router-comparison]                                     |
+| Supported Query Syntax                             | Promise, REST, GraphQL                   | Promise, REST, GraphQL      | GraphQL                                    | Promise, REST, GraphQL               | Promise, REST, GraphQL                                                    |
+| Supported Frameworks                               | React                                    | React                       | React + Others                             | Any                                  | React                                                                     |
+| Caching Strategy                                   | Hierarchical Key -> Value                | Unique Key -> Value         | Normalized Schema                          | Unique Key -> Value                  | Nested Route -> value                                                     |
+| Cache Key Strategy                                 | JSON                                     | JSON                        | GraphQL Query                              | JSON                                 | Route Path                                                                |
+| Cache Change Detection                             | Deep Compare Keys (Stable Serialization) | Shallow Compare Keys        | Deep Compare Keys (Unstable Serialization) | Key Referential Equality (===)       | Route Change                                                              |
+| Data Change Detection                              | Deep Comparison + Structural Sharing     | Deep Compare (via `dequal`) | Deep Compare (Unstable Serialization)      | Key Referential Equality (===)       | Loader Run                                                                |
+| Data Memoization                                   | Full Structural Sharing                  | Identity (===)              | Normalized Identity                        | Identity (===)                       | Identity (===)                                                            |
+| Bundle Size                                        | [![][bp-react-query]][bpl-react-query]   | [![][bp-swr]][bpl-swr]      | [![][bp-apollo]][bpl-apollo]               | [![][bp-rtk-query]][bpl-rtk-query]   | [![][bp-react-router]][bpl-react-router] + [![][bp-history]][bpl-history] |
+| API Definition Location                            | Component, External Config               | Component                   | GraphQL Schema                             | External Config                      | Route Tree Configuration                                                  |
+| Queries                                            | ✅                                       | ✅                          | ✅                                         | ✅                                   | ✅                                                                        |
+| Cache Persistence                                  | ✅                                       | ✅                          | ✅                                         | ✅                                   | 🛑 Active Routes Only <sup>8</sup>                                        |
+| Devtools                                           | ✅                                       | 🟡                          | ✅                                         | ✅                                   | 🛑                                                                        |
+| Polling/Intervals                                  | ✅                                       | ✅                          | ✅                                         | ✅                                   | 🛑                                                                        |
+| Parallel Queries                                   | ✅                                       | ✅                          | ✅                                         | ✅                                   | ✅                                                                        |
+| Dependent Queries                                  | ✅                                       | ✅                          | ✅                                         | ✅                                   | ✅                                                                        |
+| Paginated Queries                                  | ✅                                       | ✅                          | ✅                                         | ✅                                   | ✅                                                                        |
+| Infinite Queries                                   | ✅                                       | ✅                          | ✅                                         | 🛑                                   | 🛑                                                                        |
+| Bi-directional Infinite Queries                    | ✅                                       | 🔶                          | 🔶                                         | 🛑                                   | 🛑                                                                        |
+| Infinite Query Refetching                          | ✅                                       | ✅                          | 🛑                                         | 🛑                                   | 🛑                                                                        |
+| Lagged Query Data<sup>1</sup>                      | ✅                                       | 🔶                          | 🛑                                         | ✅                                   | ✅                                                                        |
+| Selectors                                          | ✅                                       | 🛑                          | ✅                                         | ✅                                   | N/A                                                                       |
+| Initial Data                                       | ✅                                       | ✅                          | ✅                                         | ✅                                   | ✅                                                                        |
+| Scroll Recovery                                    | ✅                                       | ✅                          | ✅                                         | ✅                                   | ✅                                                                        |
+| Cache Manipulation                                 | ✅                                       | ✅                          | ✅                                         | ✅                                   | 🛑                                                                        |
+| Outdated Query Dismissal                           | ✅                                       | ✅                          | ✅                                         | ✅                                   | ✅                                                                        |
+| Render Batching & Optimization<sup>2</sup>         | ✅                                       | 🛑                          | 🛑                                         | ✅                                   | ✅                                                                        |
+| Auto Garbage Collection                            | ✅                                       | 🛑                          | 🛑                                         | ✅                                   | N/A                                                                       |
+| Mutation Hooks                                     | ✅                                       | 🟡                          | ✅                                         | ✅                                   | ✅                                                                        |
+| Offline Mutation Support                           | ✅                                       | 🛑                          | 🟡                                         | 🛑                                   | 🛑                                                                        |
+| Prefetching APIs                                   | ✅                                       | 🔶                          | ✅                                         | ✅                                   | ✅                                                                        |
+| Query Cancellation                                 | ✅                                       | 🛑                          | 🛑                                         | 🛑                                   | ✅                                                                        |
+| Partial Query Matching<sup>3</sup>                 | ✅                                       | 🛑                          | 🛑                                         | ✅                                   | N/A                                                                       |
+| Stale While Revalidate                             | ✅                                       | ✅                          | ✅                                         | ✅                                   | 🛑                                                                        |
+| Stale Time Configuration                           | ✅                                       | 🛑<sup>7</sup>              | 🛑                                         | ✅                                   | 🛑                                                                        |
+| Pre-usage Query/Mutation Configuration<sup>4</sup> | ✅                                       | 🛑                          | 🛑                                         | ✅                                   | ✅                                                                        |
+| Window Focus Refetching                            | ✅                                       | ✅                          | 🛑                                         | 🔶                                   | 🛑                                                                        |
+| Network Status Refetching                          | ✅                                       | ✅                          | ✅                                         | 🔶                                   | 🛑                                                                        |
+| General Cache Dehydration/Rehydration              | ✅                                       | 🛑                          | ✅                                         | ✅                                   | ✅                                                                        |
+| Offline Caching                                    | ✅ (Experimental)                        | 🛑                          | ✅                                         | 🔶                                   | 🛑                                                                        |
+| React Suspense (Experimental)                      | ✅                                       | ✅                          | 🛑                                         | 🛑                                   | ✅                                                                        |
+| Abstracted/Agnostic Core                           | ✅                                       | 🛑                          | ✅                                         | ✅                                   | 🛑                                                                        |
+| Automatic Refetch after Mutation<sup>5</sup>       | 🔶                                       | 🔶                          | ✅                                         | ✅                                   | ✅                                                                        |
+| Normalized Caching<sup>6</sup>                     | 🛑                                       | 🛑                          | ✅                                         | 🛑                                   | 🛑                                                                        |
 
 ### Notes
 
@@ -76,7 +77,7 @@ Feature/Capability Key:
 
 > **<sup>7</sup> SWR's Immutable Mode** - SWR ships with an "immutable" mode that does allow you to only fetch a query once for the life of the cache, but it still does not have the concept of stale-time or conditional auto-revalidation
 
-> **<sup>8</sup> RTK-Query's bundle size** [can vary][rtk-query-bundle-size] depending on whether you already use redux-toolkit or not
+> **<sup>8</sup> React Router cache persistence** - React Router does not cache data beyond the currently matched routes. If a route is left, its data is lost.
 
 <!-- -->
 
@@ -112,3 +113,13 @@ Feature/Capability Key:
 [stars-rtk-query]: https://img.shields.io/github/stars/reduxjs/redux-toolkit?label=🌟
 [bpl-rtk]: https://bundlephobia.com/result?p=@reduxjs/toolkit
 [bpl-rtk-query]: https://bundlephobia.com/package/@reduxjs/toolkit
+
+<!-- -->
+
+[react-router]: https://github.com/remix-run/react-router
+[bp-react-router]: https://badgen.net/bundlephobia/minzip/react-router-dom?label=💾
+[gh-react-router]: https://github.com/remix-run/react-router
+[stars-react-router]: https://img.shields.io/github/stars/remix-run/react-router?label=%F0%9F%8C%9F
+[bpl-react-router]: https://bundlephobia.com/result?p=react-router-dom
+[bp-history]: https://badgen.net/bundlephobia/minzip/history?label=💾
+[bpl-history]: https://bundlephobia.com/result?p=history
diff --git a/docs/src/pages/guides/mutations.md b/docs/src/pages/guides/mutations.md
index 47e32fafe..ac38a5a42 100644
--- a/docs/src/pages/guides/mutations.md
+++ b/docs/src/pages/guides/mutations.md
@@ -195,7 +195,7 @@ useMutation(addTodo, {
   mutate(todo, {
     onSuccess: (data, error, variables, context) => {
       // Will execute only once, for the last mutation (Todo 3),
-      // regardless which mutation resolves first 
+      // regardless which mutation resolves first
     },
   })
 })
@@ -279,6 +279,49 @@ hydrate(queryClient, state)
 queryClient.resumePausedMutations()
 ```
 
+### Persisting Offline mutations
+
+If you persist offline mutations with the [persistQueryClient plugin](../plugins/persistQueryClient), mutations cannot be resumed when the page is reloaded unless you provide a default mutation function.
+
+This is a technical limitation. When persisting to an external storage, only the state of mutations is persisted, as functions cannot be serialized. After hydration, the component that triggeres the mutation might not be mounted, so calling `resumePausedMutations` might yield an error: `No mutationFn found`.
+
+```js
+const persister = createWebStoragePersister({
+  storage: window.localStorage,
+})
+const queryClient = new QueryClient({
+  defaultOptions: {
+    queries: {
+      cacheTime: 1000 * 60 * 60 * 24, // 24 hours
+    },
+  },
+})
+
+// we need a default mutation function so that paused mutations can resume after a page reload
+queryClient.setMutationDefaults(['todos'], {
+  mutationFn: ({ id, data }) => {
+    return api.upateTodo(id, data)
+  },
+})
+
+export default function App() {
+  return (
+    <PersistQueryClientProvider
+      client={queryClient}
+      persistOptions={{ persister }}
+      onSuccess={() => {
+        // resume mutations after initial restore from localStorage was successful
+        queryClient.resumePausedMutations()
+      }}
+    >
+      <RestOfTheApp />
+    </PersistQueryClientProvider>
+  )
+}
+```
+
+We also have an extensive [offline example](../examples/offline) that covers both queries and mutations.
+
 ## Further reading
 
 For more information about mutations, have a look at [#12: Mastering Mutations in React Query](../community/tkdodos-blog#12-mastering-mutations-in-react-query) from
diff --git a/src/devtools/Explorer.tsx b/src/devtools/Explorer.tsx
index f4835e71d..cc7dbc2c4 100644
--- a/src/devtools/Explorer.tsx
+++ b/src/devtools/Explorer.tsx
@@ -1,6 +1,6 @@
 import React from 'react'
 
-import { styled } from './utils'
+import { displayValue, styled } from './utils'
 
 export const Entry = styled('div', {
   fontFamily: 'Menlo, monospace',
@@ -118,7 +118,7 @@ export const DefaultRenderer: Renderer = ({
             subEntryPages.length === 1 ? (
               <SubEntries>
                 {subEntries.map(entry => (
-                  <HandleEntry entry={entry} />
+                  <HandleEntry key={entry.label} entry={entry} />
                 ))}
               </SubEntries>
             ) : (
@@ -141,7 +141,7 @@ export const DefaultRenderer: Renderer = ({
                       {expandedPages.includes(index) ? (
                         <SubEntries>
                           {entries.map(entry => (
-                            <HandleEntry entry={entry} />
+                            <HandleEntry key={entry.label} entry={entry} />
                           ))}
                         </SubEntries>
                       ) : null}
@@ -154,10 +154,7 @@ export const DefaultRenderer: Renderer = ({
         </>
       ) : (
         <>
-          <Label>{label}:</Label>{' '}
-          <Value>
-            {JSON.stringify(value, Object.getOwnPropertyNames(Object(value)))}
-          </Value>
+          <Label>{label}:</Label> <Value>{displayValue(value)}</Value>
         </>
       )}
     </Entry>
diff --git a/src/devtools/utils.ts b/src/devtools/utils.ts
index bc781a182..735e4fa45 100644
--- a/src/devtools/utils.ts
+++ b/src/devtools/utils.ts
@@ -127,6 +127,17 @@ export function useSafeState<T>(initialState: T): [T, (value: T) => void] {
   return [state, safeSetState]
 }
 
+/**
+ * Displays a string regardless the type of the data
+ * @param {unknown} value Value to be stringified
+ */
+export const displayValue = (value: unknown) => {
+  const name = Object.getOwnPropertyNames(Object(value))
+  const newValue = typeof value === 'bigint' ? `${value.toString()}n` : value
+
+  return JSON.stringify(newValue, name)
+}
+
 /**
  * Schedules a microtask.
  * This can be useful to schedule state updates after rendering.
diff --git a/src/persistQueryClient/persist.ts b/src/persistQueryClient/persist.ts
index 52ecb7126..13af8d625 100644
--- a/src/persistQueryClient/persist.ts
+++ b/src/persistQueryClient/persist.ts
@@ -119,15 +119,28 @@ export async function persistQueryClientSave({
 }
 
 /**
- * Subscribe to QueryCache updates (for persisting)
+ * Subscribe to QueryCache and MutationCache updates (for persisting)
  * @returns an unsubscribe function (to discontinue monitoring)
  */
 export function persistQueryClientSubscribe(
   props: PersistedQueryClientSaveOptions
 ) {
-  return props.queryClient.getQueryCache().subscribe(() => {
-    persistQueryClientSave(props)
-  })
+  const unsubscribeQueryCache = props.queryClient
+    .getQueryCache()
+    .subscribe(() => {
+      persistQueryClientSave(props)
+    })
+
+  const unusbscribeMutationCache = props.queryClient
+    .getMutationCache()
+    .subscribe(() => {
+      persistQueryClientSave(props)
+    })
+
+  return () => {
+    unsubscribeQueryCache()
+    unusbscribeMutationCache()
+  }
 }
 
 /**


Test patch:
diff --git a/src/devtools/tests/Explorer.test.tsx b/src/devtools/tests/Explorer.test.tsx
index 7a14ad404..f4077f701 100644
--- a/src/devtools/tests/Explorer.test.tsx
+++ b/src/devtools/tests/Explorer.test.tsx
@@ -2,6 +2,7 @@ import React from 'react'
 import { fireEvent, render, screen } from '@testing-library/react'
 
 import { chunkArray, DefaultRenderer } from '../Explorer'
+import { displayValue } from '../utils'
 
 describe('Explorer', () => {
   describe('chunkArray', () => {
@@ -54,4 +55,14 @@ describe('Explorer', () => {
       expect(toggleExpanded).toHaveBeenCalledTimes(1)
     })
   })
+
+  describe('displayValue', () => {
+    it('when the value is a boolean', () => {
+      expect(displayValue(true)).toBe('true')
+    })
+
+    it('when the value is a BigInt', () => {
+      expect(displayValue(BigInt(1))).toBe('"1n"')
+    })
+  })
 })
diff --git a/src/persistQueryClient/tests/persist.test.tsx b/src/persistQueryClient/tests/persist.test.tsx
new file mode 100644
index 000000000..da583a38f
--- /dev/null
+++ b/src/persistQueryClient/tests/persist.test.tsx
@@ -0,0 +1,49 @@
+import { createQueryClient } from '../../reactjs/tests/utils'
+import { sleep } from '../../core/utils'
+import {
+  PersistedClient,
+  Persister,
+  persistQueryClientSubscribe,
+} from '../persist'
+
+const createMockPersister = (): Persister => {
+  let storedState: PersistedClient | undefined
+
+  return {
+    async persistClient(persistClient: PersistedClient) {
+      storedState = persistClient
+    },
+    async restoreClient() {
+      await sleep(10)
+      return storedState
+    },
+    removeClient() {
+      storedState = undefined
+    },
+  }
+}
+
+describe('persistQueryClientSubscribe', () => {
+  test('should persist mutations', async () => {
+    const queryClient = createQueryClient()
+
+    const persister = createMockPersister()
+
+    const unsubscribe = persistQueryClientSubscribe({
+      queryClient,
+      persister,
+      dehydrateOptions: { shouldDehydrateMutation: () => true },
+    })
+
+    queryClient.getMutationCache().build(queryClient, {
+      mutationFn: async (text: string) => text,
+      variables: 'todo',
+    })
+
+    const result = await persister.restoreClient()
+
+    expect(result?.clientState.mutations).toHaveLength(1)
+
+    unsubscribe()
+  })
+})