snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
Some checks failed
autofix.ci / autofix (push) Failing after 4s
Release / Release (push) Has been skipped
GitHub Actions Security Analysis / Run zizmor (push) Failing after 2s

This commit is contained in:
upstream-mirror
2026-09-16 01:13:08 +05:00
commit 3a013ccdfe
3570 changed files with 490194 additions and 0 deletions

View File

@@ -0,0 +1,541 @@
# @tanstack/solid-query-persist-client
## 5.102.8
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.102.8
- @tanstack/solid-query@5.102.8
## 5.102.7
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.102.7
- @tanstack/solid-query@5.102.7
## 5.102.6
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.102.6
- @tanstack/solid-query@5.102.6
## 5.102.5
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.102.5
- @tanstack/solid-query@5.102.5
## 5.102.4
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.102.4
- @tanstack/solid-query@5.102.4
## 5.102.3
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.102.3
- @tanstack/solid-query@5.102.3
## 5.102.2
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.102.2
- @tanstack/solid-query@5.102.2
## 5.102.1
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.102.1
- @tanstack/solid-query@5.102.1
## 5.102.0
### Patch Changes
- Updated dependencies [[`6e3d521`](https://github.com/TanStack/query/commit/6e3d521fe54f78624e53c1c6f9cadd678504bee8), [`294d4e6`](https://github.com/TanStack/query/commit/294d4e62c4f7d674574a4903eef2a1bc3dd1413b), [`2215bb0`](https://github.com/TanStack/query/commit/2215bb031139cdc8a84751b37a485c38ca9d2b6e), [`1ef4208`](https://github.com/TanStack/query/commit/1ef42087c9a266c2137d2ef645cbcc662f60ac93), [`47d49d3`](https://github.com/TanStack/query/commit/47d49d31aa16684811257da071679d08d8726ddc)]:
- @tanstack/solid-query@5.102.0
- @tanstack/query-persist-client-core@5.102.0
## 5.101.4
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.101.4
- @tanstack/solid-query@5.101.4
## 5.101.3
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.101.3
- @tanstack/solid-query@5.101.3
## 5.101.2
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.101.2
- @tanstack/solid-query@5.101.2
## 5.101.1
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.101.1
- @tanstack/solid-query@5.101.1
## 5.101.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.101.0
- @tanstack/solid-query@5.101.0
## 5.100.14
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.14
- @tanstack/solid-query@5.100.14
## 5.100.13
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.13
- @tanstack/solid-query@5.100.13
## 5.100.12
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.12
- @tanstack/solid-query@5.100.12
## 5.100.11
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.11
- @tanstack/solid-query@5.100.11
## 5.100.10
### Patch Changes
- fix(query-devtools): remove experimentalDts to prevent solid-js type leak ([#10694](https://github.com/TanStack/query/pull/10694))
- Updated dependencies [[`4d130b9`](https://github.com/TanStack/query/commit/4d130b992d2ac396d75f921bfc530dd3a9d50577)]:
- @tanstack/solid-query@5.100.10
- @tanstack/query-persist-client-core@5.100.10
## 5.100.9
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.9
- @tanstack/solid-query@5.100.9
## 5.100.8
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.8
- @tanstack/solid-query@5.100.8
## 5.100.7
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.7
- @tanstack/solid-query@5.100.7
## 5.100.6
### Patch Changes
- Updated dependencies [[`3af3a5d`](https://github.com/TanStack/query/commit/3af3a5ded3fbaf5a06403d7561b83124dbbcb243)]:
- @tanstack/solid-query@5.100.6
- @tanstack/query-persist-client-core@5.100.6
## 5.100.5
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.5
- @tanstack/solid-query@5.100.5
## 5.100.4
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.4
- @tanstack/solid-query@5.100.4
## 5.100.3
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.3
- @tanstack/solid-query@5.100.3
## 5.100.2
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.2
- @tanstack/solid-query@5.100.2
## 5.100.1
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.1
- @tanstack/solid-query@5.100.1
## 5.100.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.100.0
- @tanstack/solid-query@5.100.0
## 5.99.2
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.99.2
- @tanstack/solid-query@5.99.2
## 5.99.1
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.99.1
- @tanstack/solid-query@5.99.1
## 5.99.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.99.0
- @tanstack/solid-query@5.99.0
## 5.98.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.98.0
- @tanstack/solid-query@5.98.0
## 5.97.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.97.0
- @tanstack/solid-query@5.97.0
## 5.96.2
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.96.2
- @tanstack/solid-query@5.96.2
## 5.96.1
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.96.1
- @tanstack/solid-query@5.96.1
## 5.96.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.96.0
- @tanstack/solid-query@5.96.0
## 5.95.2
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.95.2
- @tanstack/solid-query@5.95.2
## 5.95.1
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.95.1
- @tanstack/solid-query@5.95.1
## 5.95.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.95.0
- @tanstack/solid-query@5.95.0
## 5.94.5
### Patch Changes
- fix(\*): resolve issue about excluded build directory ([#10312](https://github.com/TanStack/query/pull/10312))
- Updated dependencies [[`4b6536d`](https://github.com/TanStack/query/commit/4b6536dfce99036f4e37f52943c6fed3ad0e0a18)]:
- @tanstack/query-persist-client-core@5.94.5
- @tanstack/solid-query@5.94.5
## 5.94.4
### Patch Changes
- chore: fixed version ([#10064](https://github.com/TanStack/query/pull/10064))
- Updated dependencies [[`4c75210`](https://github.com/TanStack/query/commit/4c75210ce8235fe3d39b67e1029eff11278927cc)]:
- @tanstack/query-persist-client-core@5.94.4
- @tanstack/solid-query@5.94.4
## 5.90.28
### Patch Changes
- fix(streamedQuery): maintain error state on reset refetch with initialData defined ([#10287](https://github.com/TanStack/query/pull/10287))
- Updated dependencies [[`248975e`](https://github.com/TanStack/query/commit/248975e896f585f6eaa505c796e73fcf7bfd1eec)]:
- @tanstack/query-persist-client-core@5.92.4
- @tanstack/solid-query@5.91.3
## 5.90.27
### Patch Changes
- Updated dependencies [[`a89aab9`](https://github.com/TanStack/query/commit/a89aab975581c25c113a26c8af486b4cafad272a)]:
- @tanstack/solid-query@5.91.2
- @tanstack/query-persist-client-core@5.92.3
## 5.90.26
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.92.2
- @tanstack/solid-query@5.91.1
## 5.90.25
### Patch Changes
- Updated dependencies [[`e505568`](https://github.com/TanStack/query/commit/e505568f4d51c8281d38e9687091094b7d32a405)]:
- @tanstack/query-persist-client-core@5.92.1
## 5.90.24
### Patch Changes
- Updated dependencies [[`978fc52`](https://github.com/TanStack/query/commit/978fc52728a8b9eb33f0a82f4ddf42a95815bd7f)]:
- @tanstack/query-persist-client-core@5.92.0
## 5.90.23
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.19
- @tanstack/solid-query@5.90.23
## 5.90.22
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.18
- @tanstack/solid-query@5.90.22
## 5.90.21
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.17
- @tanstack/solid-query@5.90.21
## 5.90.20
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.16
- @tanstack/solid-query@5.90.20
## 5.90.19
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.15
- @tanstack/solid-query@5.90.19
## 5.90.18
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.14
- @tanstack/solid-query@5.90.18
## 5.90.17
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.13
- @tanstack/solid-query@5.90.17
## 5.90.16
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.12
- @tanstack/solid-query@5.90.16
## 5.90.15
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.11
- @tanstack/solid-query@5.90.15
## 5.90.14
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.10
- @tanstack/solid-query@5.90.14
## 5.90.13
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.9
- @tanstack/solid-query@5.90.13
## 5.90.12
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.8
- @tanstack/solid-query@5.90.12
## 5.90.11
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.7
- @tanstack/solid-query@5.90.11
## 5.90.10
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.6
- @tanstack/solid-query@5.90.10
## 5.90.9
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.5
- @tanstack/solid-query@5.90.8
## 5.90.8
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.4
- @tanstack/solid-query@5.90.6
## 5.90.7
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.3
- @tanstack/solid-query@5.90.5
## 5.90.6
### Patch Changes
- Updated dependencies []:
- @tanstack/query-persist-client-core@5.91.2
- @tanstack/solid-query@5.90.4
## 5.90.5
### Patch Changes
- Updated dependencies [[`846d53d`](https://github.com/TanStack/query/commit/846d53d98992d50606c40634efa43dea9965b787)]:
- @tanstack/query-persist-client-core@5.91.1
## 5.90.4
### Patch Changes
- Updated dependencies [[`5cd86c6`](https://github.com/TanStack/query/commit/5cd86c6ef1720b87b13e1ab70ee823616f1f029a)]:
- @tanstack/query-persist-client-core@5.91.0

View File

@@ -0,0 +1,5 @@
// @ts-check
import rootConfig from './root.eslint.config.js'
export default [...rootConfig]

View File

@@ -0,0 +1,80 @@
{
"name": "@tanstack/solid-query-persist-client",
"version": "5.102.8",
"description": "Solid.js bindings to work with persisters in TanStack/solid-query",
"author": "tannerlinsley",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/TanStack/query.git",
"directory": "packages/solid-query-persist-client"
},
"homepage": "https://tanstack.com/query",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"scripts": {
"clean": "premove ./build ./coverage ./dist-ts ./.cache/test-types",
"compile": "tsc --project tsconfig.json",
"test:eslint": "eslint --concurrency=auto ./src",
"test:types": "npm-run-all --serial test:types:*",
"test:types:ts56": "node ../../node_modules/typescript56/lib/tsc.js --project tsconfig.json --outDir .cache/test-types/ts56 --tsBuildInfoFile .cache/test-types/ts56.tsbuildinfo",
"test:types:ts57": "node ../../node_modules/typescript57/lib/tsc.js --project tsconfig.json --outDir .cache/test-types/ts57 --tsBuildInfoFile .cache/test-types/ts57.tsbuildinfo",
"test:types:ts58": "node ../../node_modules/typescript58/lib/tsc.js --project tsconfig.json --outDir .cache/test-types/ts58 --tsBuildInfoFile .cache/test-types/ts58.tsbuildinfo",
"test:types:ts59": "node ../../node_modules/typescript59/lib/tsc.js --project tsconfig.json --outDir .cache/test-types/ts59 --tsBuildInfoFile .cache/test-types/ts59.tsbuildinfo",
"test:types:tscurrent": "tsc --project tsconfig.json --outDir .cache/test-types/tscurrent --tsBuildInfoFile .cache/test-types/tscurrent.tsbuildinfo",
"test:types:ts70": "node ../../node_modules/typescript70/lib/tsc.js --project tsconfig.json --outDir .cache/test-types/ts70 --tsBuildInfoFile .cache/test-types/ts70.tsbuildinfo",
"test:lib": "vitest",
"test:lib:dev": "pnpm run test:lib --watch",
"test:build": "publint --strict && attw --pack",
"build": "tsdown --tsconfig tsconfig.prod.json"
},
"type": "module",
"types": "./build/index.d.ts",
"main": "./build/index.cjs",
"module": "./build/index.js",
"exports": {
"@tanstack/custom-condition": "./src/index.ts",
"development": {
"import": {
"types": "./build/index.d.ts",
"default": "./build/dev.js"
},
"require": {
"types": "./build/index.d.cts",
"default": "./build/dev.cjs"
}
},
"import": {
"types": "./build/index.d.ts",
"default": "./build/index.js"
},
"require": {
"types": "./build/index.d.cts",
"default": "./build/index.cjs"
}
},
"sideEffects": false,
"files": [
"build",
"src",
"!src/__tests__"
],
"dependencies": {
"@tanstack/query-persist-client-core": "workspace:*"
},
"devDependencies": {
"@solidjs/testing-library": "^0.8.10",
"@tanstack/query-test-utils": "workspace:*",
"@tanstack/solid-query": "workspace:*",
"npm-run-all2": "^5.0.0",
"solid-js": "^1.9.7",
"unplugin-solid": "^2.0.0",
"vite-plugin-solid": "^2.11.6"
},
"peerDependencies": {
"@tanstack/solid-query": "workspace:^",
"solid-js": "^1.6.0"
}
}

View File

@@ -0,0 +1 @@
../../eslint.config.js

View File

@@ -0,0 +1,52 @@
import {
persistQueryClientRestore,
persistQueryClientSubscribe,
} from '@tanstack/query-persist-client-core'
import { createEffect, createMemo, createSignal, onCleanup } from 'solid-js'
import { IsRestoringProvider, QueryClientProvider } from '@tanstack/solid-query'
import type { PersistQueryClientOptions } from '@tanstack/query-persist-client-core'
import type { OmitKeyof, QueryClientProviderProps } from '@tanstack/solid-query'
import type { JSX } from 'solid-js'
export type PersistQueryClientProviderProps = QueryClientProviderProps & {
persistOptions: OmitKeyof<PersistQueryClientOptions, 'queryClient'>
onSuccess?: () => void
onError?: () => void
}
export const PersistQueryClientProvider = (
props: PersistQueryClientProviderProps,
): JSX.Element => {
const [isRestoring, setIsRestoring] = createSignal(true)
const options = createMemo(() => ({
...props.persistOptions,
queryClient: props.client,
}))
createEffect(() => {
setIsRestoring(true)
persistQueryClientRestore(options())
.then(() => props.onSuccess?.())
.catch(() => props.onError?.())
.finally(() => {
setIsRestoring(false)
})
})
createEffect(() => {
let unsubscribe = () => {}
if (!isRestoring()) {
unsubscribe = persistQueryClientSubscribe(options())
}
onCleanup(() => unsubscribe())
})
return (
<QueryClientProvider client={props.client}>
<IsRestoringProvider value={isRestoring}>
{props.children}
</IsRestoringProvider>
</QueryClientProvider>
)
}

View File

@@ -0,0 +1,613 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { render, screen } from '@solidjs/testing-library'
import { QueryClient, noop, useQueries, useQuery } from '@tanstack/solid-query'
import { persistQueryClientSave } from '@tanstack/query-persist-client-core'
import { createEffect, createSignal, onMount } from 'solid-js'
import { queryKey, sleep } from '@tanstack/query-test-utils'
import { PersistQueryClientProvider } from '../PersistQueryClientProvider'
import type {
PersistedClient,
Persister,
} from '@tanstack/query-persist-client-core'
const createMockPersister = (): Persister => {
let storedState: PersistedClient | undefined
return {
persistClient(persistClient: PersistedClient) {
storedState = persistClient
},
async restoreClient() {
return sleep(10).then(() => storedState)
},
removeClient() {
storedState = undefined
},
}
}
const createMockErrorPersister = (
removeClient: Persister['removeClient'],
): [Error, Persister] => {
const error = new Error('restore failed')
return [
error,
{
async persistClient() {
// noop
},
async restoreClient() {
await sleep(10)
throw error
},
removeClient,
},
]
}
describe('PersistQueryClientProvider', () => {
beforeEach(() => {
vi.useFakeTimers()
})
afterEach(() => {
vi.useRealTimers()
})
it('restores cache from persister', async () => {
const key = queryKey()
const states: Array<{
status: string
fetchStatus: string
data: string | undefined
}> = []
const queryClient = new QueryClient()
void queryClient
.query({
queryKey: key,
queryFn: () => sleep(10).then(() => 'hydrated'),
})
.catch(noop)
await vi.advanceTimersByTimeAsync(10)
const persister = createMockPersister()
persistQueryClientSave({ queryClient, persister })
await vi.advanceTimersByTimeAsync(0)
queryClient.clear()
function Page() {
const state = useQuery(() => ({
queryKey: key,
queryFn: () => sleep(10).then(() => 'fetched'),
}))
createEffect(() =>
states.push({
status: state.status,
fetchStatus: state.fetchStatus,
data: state.data,
}),
)
return (
<div>
<h1>{state.data}</h1>
<h2>fetchStatus: {state.fetchStatus}</h2>
</div>
)
}
render(() => (
<PersistQueryClientProvider
client={queryClient}
persistOptions={{ persister }}
>
<Page />
</PersistQueryClientProvider>
))
expect(screen.getByText('fetchStatus: idle')).toBeInTheDocument()
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('hydrated')).toBeInTheDocument()
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('fetched')).toBeInTheDocument()
expect(states).toHaveLength(3)
expect(states[0]).toStrictEqual({
status: 'pending',
fetchStatus: 'idle',
data: undefined,
})
expect(states[1]).toStrictEqual({
status: 'success',
fetchStatus: 'fetching',
data: 'hydrated',
})
expect(states[2]).toStrictEqual({
status: 'success',
fetchStatus: 'idle',
data: 'fetched',
})
})
it('should also put useQueries into idle state', async () => {
const key = queryKey()
const states: Array<{
status: string
fetchStatus: string
data: string | undefined
}> = []
const queryClient = new QueryClient()
void queryClient
.query({
queryKey: key,
queryFn: () => sleep(10).then(() => 'hydrated'),
})
.catch(noop)
await vi.advanceTimersByTimeAsync(10)
const persister = createMockPersister()
persistQueryClientSave({ queryClient, persister })
await vi.advanceTimersByTimeAsync(0)
queryClient.clear()
function Page() {
const [state] = useQueries(() => ({
queries: [
{
queryKey: key,
queryFn: () => sleep(10).then(() => 'fetched'),
},
],
}))
createEffect(() =>
states.push({
status: state.status,
fetchStatus: state.fetchStatus,
data: state.data,
}),
)
return (
<div>
<h1>{state.data}</h1>
<h2>fetchStatus: {state.fetchStatus}</h2>
</div>
)
}
render(() => (
<PersistQueryClientProvider
client={queryClient}
persistOptions={{ persister }}
>
<Page />
</PersistQueryClientProvider>
))
expect(screen.getByText('fetchStatus: idle')).toBeInTheDocument()
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('hydrated')).toBeInTheDocument()
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('fetched')).toBeInTheDocument()
expect(states).toHaveLength(3)
expect(states[0]).toStrictEqual({
status: 'pending',
fetchStatus: 'idle',
data: undefined,
})
expect(states[1]).toStrictEqual({
status: 'success',
fetchStatus: 'fetching',
data: 'hydrated',
})
expect(states[2]).toStrictEqual({
status: 'success',
fetchStatus: 'idle',
data: 'fetched',
})
})
it('should show initialData while restoring', async () => {
const key = queryKey()
const states: Array<{
status: string
fetchStatus: string
data: string | undefined
}> = []
const queryClient = new QueryClient()
void queryClient
.query({
queryKey: key,
queryFn: () => sleep(10).then(() => 'hydrated'),
})
.catch(noop)
await vi.advanceTimersByTimeAsync(10)
const persister = createMockPersister()
persistQueryClientSave({ queryClient, persister })
await vi.advanceTimersByTimeAsync(0)
queryClient.clear()
function Page() {
const state = useQuery(() => ({
queryKey: key,
queryFn: () => sleep(10).then(() => 'fetched'),
initialData: 'initial',
// make sure that initial data is older than the hydration data
// otherwise initialData would be newer and takes precedence
initialDataUpdatedAt: 1,
}))
createEffect(() =>
states.push({
status: state.status,
fetchStatus: state.fetchStatus,
data: state.data,
}),
)
return (
<div>
<h1>{state.data}</h1>
<h2>fetchStatus: {state.fetchStatus}</h2>
</div>
)
}
render(() => (
<PersistQueryClientProvider
client={queryClient}
persistOptions={{ persister }}
>
<Page />
</PersistQueryClientProvider>
))
expect(screen.getByText('initial')).toBeInTheDocument()
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('hydrated')).toBeInTheDocument()
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('fetched')).toBeInTheDocument()
expect(states).toHaveLength(3)
expect(states[0]).toStrictEqual({
status: 'success',
fetchStatus: 'idle',
data: 'initial',
})
expect(states[1]).toStrictEqual({
status: 'success',
fetchStatus: 'fetching',
data: 'hydrated',
})
expect(states[2]).toStrictEqual({
status: 'success',
fetchStatus: 'idle',
data: 'fetched',
})
})
it('should not refetch after restoring when data is fresh', async () => {
const key = queryKey()
const states: Array<{
status: string
fetchStatus: string
data: string | undefined
}> = []
const queryClient = new QueryClient()
void queryClient
.query({
queryKey: key,
queryFn: () => sleep(10).then(() => 'hydrated'),
})
.catch(noop)
await vi.advanceTimersByTimeAsync(10)
const persister = createMockPersister()
persistQueryClientSave({ queryClient, persister })
await vi.advanceTimersByTimeAsync(0)
queryClient.clear()
let fetched = false
function Page() {
const state = useQuery(() => ({
queryKey: key,
queryFn: () =>
sleep(10).then(() => {
fetched = true
return 'fetched'
}),
staleTime: Infinity,
}))
createEffect(() =>
states.push({
status: state.status,
fetchStatus: state.fetchStatus,
data: state.data,
}),
)
return (
<div>
<h1>data: {state.data ?? 'null'}</h1>
<h2>fetchStatus: {state.fetchStatus}</h2>
</div>
)
}
render(() => (
<PersistQueryClientProvider
client={queryClient}
persistOptions={{ persister }}
>
<Page />
</PersistQueryClientProvider>
))
expect(screen.getByText('data: null')).toBeInTheDocument()
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('data: hydrated')).toBeInTheDocument()
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('data: hydrated')).toBeInTheDocument()
expect(fetched).toBe(false)
expect(states).toHaveLength(2)
expect(states[0]).toStrictEqual({
status: 'pending',
fetchStatus: 'idle',
data: undefined,
})
expect(states[1]).toStrictEqual({
status: 'success',
fetchStatus: 'idle',
data: 'hydrated',
})
})
it('should call onSuccess after successful restoring', async () => {
const key = queryKey()
const queryClient = new QueryClient()
void queryClient
.query({
queryKey: key,
queryFn: () => sleep(10).then(() => 'hydrated'),
})
.catch(noop)
await vi.advanceTimersByTimeAsync(10)
const persister = createMockPersister()
persistQueryClientSave({ queryClient, persister })
await vi.advanceTimersByTimeAsync(0)
queryClient.clear()
function Page() {
const state = useQuery(() => ({
queryKey: key,
queryFn: () => sleep(10).then(() => 'fetched'),
}))
return (
<div>
<h1>{state.data}</h1>
<h2>fetchStatus: {state.fetchStatus}</h2>
</div>
)
}
const onSuccess = vi.fn()
render(() => (
<PersistQueryClientProvider
client={queryClient}
persistOptions={{ persister }}
onSuccess={onSuccess}
>
<Page />
</PersistQueryClientProvider>
))
expect(onSuccess).toHaveBeenCalledTimes(0)
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('hydrated')).toBeInTheDocument()
expect(onSuccess).toHaveBeenCalledTimes(1)
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('fetched')).toBeInTheDocument()
})
it('should remove cache after non-successful restoring', async () => {
const key = queryKey()
const onErrorMock = vi
.spyOn(console, 'error')
.mockImplementation(() => undefined)
const queryClient = new QueryClient()
const removeClient = vi.fn()
const onSuccess = vi.fn()
const onError = vi.fn()
const [error, persister] = createMockErrorPersister(removeClient)
function Page() {
const state = useQuery(() => ({
queryKey: key,
queryFn: () => sleep(10).then(() => 'fetched'),
}))
return (
<div>
<h1>{state.data}</h1>
<h2>fetchStatus: {state.fetchStatus}</h2>
</div>
)
}
render(() => (
<PersistQueryClientProvider
client={queryClient}
persistOptions={{ persister }}
onSuccess={onSuccess}
onError={onError}
>
<Page />
</PersistQueryClientProvider>
))
await vi.advanceTimersByTimeAsync(10)
expect(removeClient).toHaveBeenCalledTimes(1)
expect(onSuccess).toHaveBeenCalledTimes(0)
expect(onError).toHaveBeenCalledTimes(1)
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('fetched')).toBeInTheDocument()
expect(onErrorMock).toHaveBeenCalledTimes(1)
expect(onErrorMock).toHaveBeenNthCalledWith(1, error)
onErrorMock.mockRestore()
})
it('should be able to persist into multiple clients', async () => {
const key = queryKey()
const states: Array<{
status: string
fetchStatus: string
data: string | undefined
}> = []
const queryClient = new QueryClient()
void queryClient
.query({
queryKey: key,
queryFn: () => sleep(10).then(() => 'hydrated'),
})
.catch(noop)
await vi.advanceTimersByTimeAsync(10)
const persister = createMockPersister()
persistQueryClientSave({ queryClient, persister })
await vi.advanceTimersByTimeAsync(0)
queryClient.clear()
const onSuccess = vi.fn()
const queryFn1 = vi
.fn()
.mockImplementation(() => sleep(10).then(() => 'queryFn1'))
const queryFn2 = vi
.fn()
.mockImplementation(() => sleep(10).then(() => 'queryFn2'))
function App() {
const [client, setClient] = createSignal(
new QueryClient({
defaultOptions: {
queries: {
queryFn: queryFn1,
},
},
}),
)
onMount(() => {
setClient(
new QueryClient({
defaultOptions: {
queries: {
queryFn: queryFn2,
},
},
}),
)
})
return (
<PersistQueryClientProvider
client={client()}
persistOptions={{ persister }}
onSuccess={onSuccess}
>
<Page />
</PersistQueryClientProvider>
)
}
function Page() {
const state = useQuery(() => ({ queryKey: key }))
createEffect(() =>
states.push({
status: state.status,
fetchStatus: state.fetchStatus,
data: state.data as string | undefined,
}),
)
return (
<div>
<h1>{String(state.data)}</h1>
<h2>fetchStatus: {state.fetchStatus}</h2>
</div>
)
}
render(() => <App />)
await vi.advanceTimersByTimeAsync(10)
expect(screen.getByText('queryFn2')).toBeInTheDocument()
expect(queryFn1).toHaveBeenCalledTimes(0)
expect(queryFn2).toHaveBeenCalledTimes(1)
expect(onSuccess).toHaveBeenCalledTimes(1)
expect(states).toHaveLength(3)
expect(states[0]).toStrictEqual({
status: 'pending',
fetchStatus: 'idle',
data: undefined,
})
expect(states[1]).toStrictEqual({
status: 'success',
fetchStatus: 'fetching',
data: 'hydrated',
})
expect(states[2]).toStrictEqual({
status: 'success',
fetchStatus: 'idle',
data: 'queryFn2',
})
})
})

View File

@@ -0,0 +1,4 @@
// Re-export core
export * from '@tanstack/query-persist-client-core'
export * from './PersistQueryClientProvider'

View File

@@ -0,0 +1,6 @@
import '@testing-library/jest-dom/vitest'
import { cleanup } from '@solidjs/testing-library'
import { afterEach } from 'vitest'
// https://github.com/solidjs/solid-testing-library
afterEach(() => cleanup())

View File

@@ -0,0 +1,20 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist-ts",
"rootDir": ".",
"jsx": "preserve",
"jsxImportSource": "solid-js"
},
"include": [
"src",
"test-setup.ts",
"*.config.ts",
"*.config.js",
"package.json"
],
"references": [
{ "path": "../query-persist-client-core" },
{ "path": "../solid-query" }
]
}

View File

@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"incremental": false,
"composite": false,
"rootDir": "../../"
},
"include": ["src"],
"exclude": ["src/__tests__"]
}

View File

@@ -0,0 +1,42 @@
import { defineConfig } from 'tsdown'
import solid from 'unplugin-solid/rolldown'
const baseConfig = {
target: 'esnext',
platform: 'browser' as const,
format: ['esm', 'cjs'] as ['esm', 'cjs'],
outDir: 'build',
fixedExtension: false,
}
const environment = (development: boolean) => ({
NODE_ENV: development ? 'development' : 'production',
PROD: !development,
DEV: development,
SSR: false,
})
export default defineConfig([
{
...baseConfig,
entry: { index: 'src/index.ts' },
clean: true,
dts: true,
env: environment(false),
minify: {
compress: {
dropConsole: true,
dropDebugger: true,
},
},
plugins: [solid()],
},
{
...baseConfig,
entry: { dev: 'src/index.ts' },
clean: false,
dts: false,
env: environment(true),
plugins: [solid()],
},
])

View File

@@ -0,0 +1,34 @@
import { defineConfig } from 'vitest/config'
import solid from 'vite-plugin-solid'
import packageJson from './package.json'
export default defineConfig({
plugins: [solid()],
// fix from https://github.com/vitest-dev/vitest/issues/6992#issuecomment-2509408660
resolve: {
conditions: ['@tanstack/custom-condition'],
},
environments: {
ssr: {
resolve: {
conditions: ['@tanstack/custom-condition'],
},
},
},
test: {
name: packageJson.name,
dir: './src',
watch: false,
environment: 'jsdom',
setupFiles: ['test-setup.ts'],
coverage: {
enabled: !!process.env.CI,
provider: 'istanbul',
include: ['src/**/*'],
exclude: ['src/__tests__/**'],
},
typecheck: { enabled: true },
restoreMocks: true,
},
})