Skip to content

Commit 887541a

Browse files
JoviDeCroockautofix-ci[bot]TkDodo
authored
Add preact persist plugin (#10120)
* Add preact persist plugin * Add docs * Add tests * Fix type issue * ci: apply automated fixes * Fixes * Update changeset for preact-query packages --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Dominik Dorfmeister <office@dorfmeister.cc>
1 parent 561f769 commit 887541a

21 files changed

Lines changed: 696 additions & 0 deletions

.changeset/six-countries-tickle.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@tanstack/preact-query-persist-client": minor
3+
"@tanstack/preact-query": minor
4+
---
5+
6+
feat: Add preact persist plugin

docs/config.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,31 @@
15931593
"to": "framework/vue/plugins/createPersister"
15941594
}
15951595
]
1596+
},
1597+
{
1598+
"label": "preact",
1599+
"children": [
1600+
{
1601+
"label": "persistQueryClient",
1602+
"to": "framework/preact/plugins/persistQueryClient"
1603+
},
1604+
{
1605+
"label": "createSyncStoragePersister",
1606+
"to": "framework/preact/plugins/createSyncStoragePersister"
1607+
},
1608+
{
1609+
"label": "createAsyncStoragePersister",
1610+
"to": "framework/preact/plugins/createAsyncStoragePersister"
1611+
},
1612+
{
1613+
"label": "broadcastQueryClient (Experimental)",
1614+
"to": "framework/preact/plugins/broadcastQueryClient"
1615+
},
1616+
{
1617+
"label": "createPersister (Experimental)",
1618+
"to": "framework/preact/plugins/createPersister"
1619+
}
1620+
]
15961621
}
15971622
]
15981623
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
id: createAsyncStoragePersister
3+
title: createAsyncStoragePersister
4+
ref: docs/framework/react/plugins/createAsyncStoragePersister.md
5+
replace: { 'react-query': 'preact-query' }
6+
---
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
id: createPersister
3+
title: experimental_createPersister
4+
ref: docs/framework/react/plugins/createPersister.md
5+
replace: { 'react-query': 'preact-query' }
6+
---
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
id: createSyncStoragePersister
3+
title: createSyncStoragePersister
4+
ref: docs/framework/react/plugins/createSyncStoragePersister.md
5+
replace: { 'react-query': 'preact-query' }
6+
---
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// @ts-check
2+
// @ts-ignore: no types for eslint-config-preact
3+
import preact from 'eslint-config-preact'
4+
// eslint-config-preact uses typescript-eslint under the hood
5+
import tseslint from 'typescript-eslint'
6+
7+
import rootConfig from './root.eslint.config.js'
8+
9+
export default [
10+
...rootConfig,
11+
...preact,
12+
{
13+
files: ['**/*.{ts,tsx}'],
14+
languageOptions: {
15+
parser: tseslint.parser,
16+
parserOptions: {
17+
project: true,
18+
},
19+
},
20+
plugins: {
21+
'typescript-eslint': tseslint.plugin,
22+
},
23+
rules: {
24+
// Disable base rule to prevent overload false positives
25+
'no-redeclare': 'off',
26+
'no-duplicate-imports': 'off',
27+
'no-unused-vars': 'off',
28+
'import/order': 'off',
29+
'sort-imports': 'off',
30+
'no-import-assign': 'off',
31+
// TS-aware version handles overloads correctly
32+
'@typescript-eslint/no-redeclare': 'error',
33+
'@typescript-eslint/array-type': 'off',
34+
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
35+
'@typescript-eslint/no-unnecessary-condition': 'off',
36+
},
37+
},
38+
]
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"name": "@tanstack/preact-query-persist-client",
3+
"version": "5.91.0",
4+
"description": "Preact bindings to work with persisters in TanStack/preact-query",
5+
"author": "tannerlinsley",
6+
"license": "MIT",
7+
"repository": {
8+
"type": "git",
9+
"url": "git+https://github.com/TanStack/query.git",
10+
"directory": "packages/preact-query-persist-client"
11+
},
12+
"homepage": "https://tanstack.com/query",
13+
"funding": {
14+
"type": "github",
15+
"url": "https://github.com/sponsors/tannerlinsley"
16+
},
17+
"scripts": {
18+
"clean": "premove ./build ./coverage ./dist-ts",
19+
"compile": "tsc --build",
20+
"test:eslint": "eslint --concurrency=auto ./src",
21+
"test:types": "npm-run-all --serial test:types:*",
22+
"test:types:ts50": "node ../../node_modules/typescript50/lib/tsc.js --build tsconfig.legacy.json",
23+
"test:types:ts51": "node ../../node_modules/typescript51/lib/tsc.js --build tsconfig.legacy.json",
24+
"test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js --build tsconfig.legacy.json",
25+
"test:types:ts53": "node ../../node_modules/typescript53/lib/tsc.js --build tsconfig.legacy.json",
26+
"test:types:ts54": "node ../../node_modules/typescript54/lib/tsc.js --build tsconfig.legacy.json",
27+
"test:types:ts55": "node ../../node_modules/typescript55/lib/tsc.js --build tsconfig.legacy.json",
28+
"test:types:ts56": "node ../../node_modules/typescript56/lib/tsc.js --build tsconfig.legacy.json",
29+
"test:types:ts57": "node ../../node_modules/typescript57/lib/tsc.js --build tsconfig.legacy.json",
30+
"test:types:tscurrent": "tsc --build",
31+
"test:lib": "vitest --retry=3",
32+
"test:lib:dev": "pnpm run test:lib --watch",
33+
"test:build": "publint --strict && attw --pack",
34+
"build": "tsup --tsconfig tsconfig.prod.json"
35+
},
36+
"type": "module",
37+
"types": "build/legacy/index.d.ts",
38+
"main": "build/legacy/index.cjs",
39+
"module": "build/legacy/index.js",
40+
"exports": {
41+
".": {
42+
"@tanstack/custom-condition": "./src/index.ts",
43+
"import": {
44+
"types": "./build/modern/index.d.ts",
45+
"default": "./build/modern/index.js"
46+
},
47+
"require": {
48+
"types": "./build/modern/index.d.cts",
49+
"default": "./build/modern/index.cjs"
50+
}
51+
},
52+
"./package.json": "./package.json"
53+
},
54+
"sideEffects": false,
55+
"files": [
56+
"build",
57+
"src",
58+
"!src/__tests__"
59+
],
60+
"dependencies": {
61+
"@tanstack/query-persist-client-core": "workspace:*"
62+
},
63+
"devDependencies": {
64+
"@preact/preset-vite": "^2.10.2",
65+
"@tanstack/preact-query": "workspace:*",
66+
"@tanstack/query-test-utils": "workspace:*",
67+
"@testing-library/preact": "^3.2.4",
68+
"eslint-config-preact": "^2.0.0",
69+
"npm-run-all2": "^5.0.0",
70+
"preact": "^10.28.0",
71+
"typescript-eslint": "^8.54.0"
72+
},
73+
"peerDependencies": {
74+
"@tanstack/preact-query": "workspace:^",
75+
"preact": "^10.0.0"
76+
}
77+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../eslint.config.js
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../scripts/getTsupConfig.js
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { useEffect, useRef, useState } from 'preact/hooks'
2+
import type { VNode } from 'preact'
3+
4+
import {
5+
persistQueryClientRestore,
6+
persistQueryClientSubscribe,
7+
} from '@tanstack/query-persist-client-core'
8+
import {
9+
IsRestoringProvider,
10+
QueryClientProvider,
11+
} from '@tanstack/preact-query'
12+
import type { PersistQueryClientOptions } from '@tanstack/query-persist-client-core'
13+
import type {
14+
OmitKeyof,
15+
QueryClientProviderProps,
16+
} from '@tanstack/preact-query'
17+
18+
export type PersistQueryClientProviderProps = QueryClientProviderProps & {
19+
persistOptions: OmitKeyof<PersistQueryClientOptions, 'queryClient'>
20+
onSuccess?: () => Promise<unknown> | unknown
21+
onError?: () => Promise<unknown> | unknown
22+
}
23+
24+
export const PersistQueryClientProvider = ({
25+
children,
26+
persistOptions,
27+
onSuccess,
28+
onError,
29+
...props
30+
}: PersistQueryClientProviderProps): VNode => {
31+
const [isRestoring, setIsRestoring] = useState(true)
32+
const refs = useRef({ persistOptions, onSuccess, onError })
33+
const didRestore = useRef(false)
34+
35+
useEffect(() => {
36+
refs.current = { persistOptions, onSuccess, onError }
37+
})
38+
39+
useEffect(() => {
40+
const options = {
41+
...refs.current.persistOptions,
42+
queryClient: props.client,
43+
}
44+
if (!didRestore.current) {
45+
didRestore.current = true
46+
persistQueryClientRestore(options)
47+
.then(() => refs.current.onSuccess?.())
48+
.catch(() => refs.current.onError?.())
49+
.finally(() => {
50+
setIsRestoring(false)
51+
})
52+
}
53+
return isRestoring ? undefined : persistQueryClientSubscribe(options)
54+
}, [props.client, isRestoring])
55+
56+
return (
57+
<QueryClientProvider {...props}>
58+
<IsRestoringProvider value={isRestoring}>{children}</IsRestoringProvider>
59+
</QueryClientProvider>
60+
)
61+
}

0 commit comments

Comments
 (0)