@tanstack/react-query 5.4.3 → 5.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/codemods/coverage/clover.xml +2 -2
- package/build/codemods/coverage/index.html +1 -1
- package/build/codemods/src/utils/index.js +8 -5
- package/build/codemods/src/utils/transformers/query-cache-transformer.js +10 -2
- package/build/codemods/src/utils/transformers/query-client-transformer.js +7 -2
- package/build/codemods/src/utils/transformers/use-query-like-transformer.js +10 -4
- package/build/codemods/src/v4/key-transformation.js +57 -9
- package/build/codemods/src/v5/keep-previous-data/README.md +32 -0
- package/build/codemods/src/v5/keep-previous-data/keep-previous-data.js +275 -0
- package/build/codemods/src/v5/keep-previous-data/utils/already-has-placeholder-data-property.js +26 -0
- package/build/legacy/useBaseQuery.cjs +7 -0
- package/build/legacy/useBaseQuery.cjs.map +1 -1
- package/build/legacy/useBaseQuery.js +7 -0
- package/build/legacy/useBaseQuery.js.map +1 -1
- package/build/modern/useBaseQuery.cjs +7 -0
- package/build/modern/useBaseQuery.cjs.map +1 -1
- package/build/modern/useBaseQuery.js +7 -0
- package/build/modern/useBaseQuery.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/useQuery.test.tsx +21 -0
- package/src/useBaseQuery.ts +8 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<coverage generated="
|
|
3
|
-
<project timestamp="
|
|
2
|
+
<coverage generated="1699027367718" clover="3.2.0">
|
|
3
|
+
<project timestamp="1699027367718" name="All files">
|
|
4
4
|
<metrics statements="0" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0" elements="0" coveredelements="0" complexity="0" loc="0" ncloc="0" packages="0" files="0" classes="0"/>
|
|
5
5
|
</project>
|
|
6
6
|
</coverage>
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
87
87
|
Code coverage generated by
|
|
88
88
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
89
|
-
at 2023-
|
|
89
|
+
at 2023-11-03T16:02:47.709Z
|
|
90
90
|
</div>
|
|
91
91
|
<script src="prettify.js"></script>
|
|
92
92
|
<script>
|
|
@@ -11,21 +11,24 @@ module.exports = ({ root, jscodeshift }) => {
|
|
|
11
11
|
return jscodeshift.identifier(identifier)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const findImportSpecifiers = () =>
|
|
14
|
+
const findImportSpecifiers = (packageName) =>
|
|
15
15
|
root
|
|
16
16
|
.find(jscodeshift.ImportDeclaration, {
|
|
17
17
|
source: {
|
|
18
|
-
value:
|
|
18
|
+
value: packageName,
|
|
19
19
|
},
|
|
20
20
|
})
|
|
21
21
|
.find(jscodeshift.ImportSpecifier, {})
|
|
22
22
|
|
|
23
|
-
const locateImports = (
|
|
23
|
+
const locateImports = (
|
|
24
|
+
identifiers,
|
|
25
|
+
packageName = '@tanstack/react-query',
|
|
26
|
+
) => {
|
|
24
27
|
const findNamespaceImportIdentifier = () => {
|
|
25
28
|
const specifier = root
|
|
26
29
|
.find(jscodeshift.ImportDeclaration, {
|
|
27
30
|
source: {
|
|
28
|
-
value:
|
|
31
|
+
value: packageName,
|
|
29
32
|
},
|
|
30
33
|
})
|
|
31
34
|
.find(jscodeshift.ImportNamespaceSpecifier)
|
|
@@ -53,7 +56,7 @@ module.exports = ({ root, jscodeshift }) => {
|
|
|
53
56
|
}
|
|
54
57
|
}
|
|
55
58
|
|
|
56
|
-
const importSpecifiers = findImportSpecifiers()
|
|
59
|
+
const importSpecifiers = findImportSpecifiers(packageName)
|
|
57
60
|
const identifierMap = {}
|
|
58
61
|
|
|
59
62
|
for (const identifier of identifiers) {
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
module.exports = ({
|
|
1
|
+
module.exports = ({
|
|
2
|
+
jscodeshift,
|
|
3
|
+
utils,
|
|
4
|
+
root,
|
|
5
|
+
packageName = '@tanstack/react-query',
|
|
6
|
+
}) => {
|
|
2
7
|
const isGetQueryCacheMethodCall = (
|
|
3
8
|
initializer,
|
|
4
9
|
importIdentifiers,
|
|
@@ -106,7 +111,10 @@ module.exports = ({ jscodeshift, utils, root }) => {
|
|
|
106
111
|
|
|
107
112
|
const execute = (replacer) => {
|
|
108
113
|
findQueryCacheMethodCalls(
|
|
109
|
-
utils.locateImports(
|
|
114
|
+
utils.locateImports(
|
|
115
|
+
['QueryCache', 'QueryClient', 'useQueryClient'],
|
|
116
|
+
packageName,
|
|
117
|
+
),
|
|
110
118
|
).replaceWith(replacer)
|
|
111
119
|
}
|
|
112
120
|
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
module.exports = ({
|
|
1
|
+
module.exports = ({
|
|
2
|
+
jscodeshift,
|
|
3
|
+
utils,
|
|
4
|
+
root,
|
|
5
|
+
packageName = '@tanstack/react-query',
|
|
6
|
+
}) => {
|
|
2
7
|
const filterQueryClientMethodCalls = (node, methods) =>
|
|
3
8
|
utils.isIdentifier(node) && methods.includes(node.name)
|
|
4
9
|
|
|
@@ -37,7 +42,7 @@ module.exports = ({ jscodeshift, utils, root }) => {
|
|
|
37
42
|
|
|
38
43
|
const execute = (methods, replacer) => {
|
|
39
44
|
findQueryClientMethodCalls(
|
|
40
|
-
utils.locateImports(['QueryClient', 'useQueryClient']),
|
|
45
|
+
utils.locateImports(['QueryClient', 'useQueryClient'], packageName),
|
|
41
46
|
methods,
|
|
42
47
|
).replaceWith(replacer)
|
|
43
48
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
module.exports = ({
|
|
1
|
+
module.exports = ({
|
|
2
|
+
jscodeshift,
|
|
3
|
+
utils,
|
|
4
|
+
root,
|
|
5
|
+
packageName = '@tanstack/react-query',
|
|
6
|
+
}) => {
|
|
2
7
|
const filterUseQueryLikeHookCalls = (node, importIdentifiers, hooks) => {
|
|
3
8
|
for (const hook of hooks) {
|
|
4
9
|
const selector = utils.getSelectorByImports(importIdentifiers, hook)
|
|
@@ -21,9 +26,10 @@ module.exports = ({ jscodeshift, utils, root }) => {
|
|
|
21
26
|
)
|
|
22
27
|
|
|
23
28
|
const execute = (hooks, replacer) => {
|
|
24
|
-
findUseQueryLikeHookCalls(
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
findUseQueryLikeHookCalls(
|
|
30
|
+
utils.locateImports(hooks, packageName),
|
|
31
|
+
hooks,
|
|
32
|
+
).replaceWith(replacer)
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
return {
|
|
@@ -9,8 +9,19 @@ const createQueryClientTransformer = require('../utils/transformers/query-client
|
|
|
9
9
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
10
10
|
const createQueryCacheTransformer = require('../utils/transformers/query-cache-transformer')
|
|
11
11
|
|
|
12
|
-
const transformQueryClientUsages = ({
|
|
13
|
-
|
|
12
|
+
const transformQueryClientUsages = ({
|
|
13
|
+
jscodeshift,
|
|
14
|
+
utils,
|
|
15
|
+
root,
|
|
16
|
+
filePath,
|
|
17
|
+
packageName,
|
|
18
|
+
}) => {
|
|
19
|
+
const transformer = createQueryClientTransformer({
|
|
20
|
+
jscodeshift,
|
|
21
|
+
utils,
|
|
22
|
+
root,
|
|
23
|
+
packageName,
|
|
24
|
+
})
|
|
14
25
|
const replacer = createKeyReplacer({ jscodeshift, root, filePath })
|
|
15
26
|
|
|
16
27
|
transformer.execute(
|
|
@@ -41,11 +52,17 @@ const transformQueryClientUsages = ({ jscodeshift, utils, root, filePath }) => {
|
|
|
41
52
|
)
|
|
42
53
|
}
|
|
43
54
|
|
|
44
|
-
const transformUseQueriesUsages = ({
|
|
55
|
+
const transformUseQueriesUsages = ({
|
|
56
|
+
jscodeshift,
|
|
57
|
+
utils,
|
|
58
|
+
root,
|
|
59
|
+
packageName,
|
|
60
|
+
}) => {
|
|
45
61
|
const transformer = createUseQueryLikeTransformer({
|
|
46
62
|
jscodeshift,
|
|
47
63
|
utils,
|
|
48
64
|
root,
|
|
65
|
+
packageName,
|
|
49
66
|
})
|
|
50
67
|
const replacer = ({ node }) => {
|
|
51
68
|
/**
|
|
@@ -82,11 +99,13 @@ const transformUseQueryLikeUsages = ({
|
|
|
82
99
|
utils,
|
|
83
100
|
root,
|
|
84
101
|
filePath,
|
|
102
|
+
packageName,
|
|
85
103
|
}) => {
|
|
86
104
|
const transformer = createUseQueryLikeTransformer({
|
|
87
105
|
jscodeshift,
|
|
88
106
|
utils,
|
|
89
107
|
root,
|
|
108
|
+
packageName,
|
|
90
109
|
})
|
|
91
110
|
|
|
92
111
|
transformer.execute(
|
|
@@ -109,8 +128,19 @@ const transformUseQueryLikeUsages = ({
|
|
|
109
128
|
)
|
|
110
129
|
}
|
|
111
130
|
|
|
112
|
-
const transformQueryCacheUsages = ({
|
|
113
|
-
|
|
131
|
+
const transformQueryCacheUsages = ({
|
|
132
|
+
jscodeshift,
|
|
133
|
+
utils,
|
|
134
|
+
root,
|
|
135
|
+
filePath,
|
|
136
|
+
packageName,
|
|
137
|
+
}) => {
|
|
138
|
+
const transformer = createQueryCacheTransformer({
|
|
139
|
+
jscodeshift,
|
|
140
|
+
utils,
|
|
141
|
+
root,
|
|
142
|
+
packageName,
|
|
143
|
+
})
|
|
114
144
|
const replacer = createKeyReplacer({ jscodeshift, root, filePath })
|
|
115
145
|
|
|
116
146
|
transformer.execute(replacer)
|
|
@@ -124,15 +154,33 @@ module.exports = (file, api) => {
|
|
|
124
154
|
|
|
125
155
|
const utils = createUtilsObject({ root, jscodeshift })
|
|
126
156
|
const filePath = file.path
|
|
157
|
+
const packageName = 'react-query'
|
|
127
158
|
|
|
128
159
|
// This function transforms usages like `useQuery` and `useMutation`.
|
|
129
|
-
transformUseQueryLikeUsages({
|
|
160
|
+
transformUseQueryLikeUsages({
|
|
161
|
+
jscodeshift,
|
|
162
|
+
utils,
|
|
163
|
+
root,
|
|
164
|
+
filePath,
|
|
165
|
+
packageName,
|
|
166
|
+
})
|
|
130
167
|
// This function transforms usages of `useQueries`.
|
|
131
|
-
transformUseQueriesUsages({
|
|
168
|
+
transformUseQueriesUsages({
|
|
169
|
+
jscodeshift,
|
|
170
|
+
utils,
|
|
171
|
+
root,
|
|
172
|
+
packageName,
|
|
173
|
+
})
|
|
132
174
|
// This function transforms usages of `QueryClient`.
|
|
133
|
-
transformQueryClientUsages({
|
|
175
|
+
transformQueryClientUsages({
|
|
176
|
+
jscodeshift,
|
|
177
|
+
utils,
|
|
178
|
+
root,
|
|
179
|
+
filePath,
|
|
180
|
+
packageName,
|
|
181
|
+
})
|
|
134
182
|
// This function transforms usages of `QueryCache`.
|
|
135
|
-
transformQueryCacheUsages({ jscodeshift, utils, root, filePath })
|
|
183
|
+
transformQueryCacheUsages({ jscodeshift, utils, root, filePath, packageName })
|
|
136
184
|
|
|
137
185
|
return root.toSource({ quote: 'single', lineTerminator: '\n' })
|
|
138
186
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
### Intro
|
|
2
|
+
|
|
3
|
+
The prerequisite for this code mod is to migrate your usages to the new syntax, so overloads for hooks and `QueryClient` methods shouldn't be available anymore.
|
|
4
|
+
|
|
5
|
+
### Affected usages
|
|
6
|
+
|
|
7
|
+
Please note, this code mod transforms usages only where the first argument is an object expression.
|
|
8
|
+
|
|
9
|
+
The following usage should be transformed by the code mod:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const { data } = useQuery({
|
|
13
|
+
queryKey: ['posts'],
|
|
14
|
+
queryFn: queryFn,
|
|
15
|
+
keepPreviousData: true,
|
|
16
|
+
})
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
But the following usage won't be transformed by the code mod, because the first argument an identifier:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const hookArgument = {
|
|
23
|
+
queryKey: ['posts'],
|
|
24
|
+
queryFn: queryFn,
|
|
25
|
+
keepPreviousData: true,
|
|
26
|
+
}
|
|
27
|
+
const { data } = useQuery(hookArgument)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Troubleshooting
|
|
31
|
+
|
|
32
|
+
In case of any errors, feel free to reach us out via Discord or open an issue. If you open an issue, please provide a code snippet as well, because without a snippet we cannot find the bug in the code mod.
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
2
|
+
const createUtilsObject = require('../../utils')
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
4
|
+
const createUseQueryLikeTransformer = require('../../utils/transformers/use-query-like-transformer')
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
6
|
+
const createQueryClientTransformer = require('../../utils/transformers/query-client-transformer')
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
8
|
+
const AlreadyHasPlaceholderDataProperty = require('./utils/already-has-placeholder-data-property')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {import('jscodeshift')} jscodeshift
|
|
12
|
+
* @param {Object} utils
|
|
13
|
+
* @param {import('jscodeshift').Collection} root
|
|
14
|
+
* @param {string} filePath
|
|
15
|
+
* @param {{keyName: "mutationKey"|"queryKey", queryClientMethods: ReadonlyArray<string>, hooks: ReadonlyArray<string>}} config
|
|
16
|
+
*/
|
|
17
|
+
const transformUsages = ({ jscodeshift, utils, root, filePath, config }) => {
|
|
18
|
+
/**
|
|
19
|
+
* @param {import('jscodeshift').CallExpression | import('jscodeshift').ExpressionStatement} node
|
|
20
|
+
* @returns {{start: number, end: number}}
|
|
21
|
+
*/
|
|
22
|
+
const getNodeLocation = (node) => {
|
|
23
|
+
const location = utils.isCallExpression(node) ? node.callee.loc : node.loc
|
|
24
|
+
const start = location.start.line
|
|
25
|
+
const end = location.end.line
|
|
26
|
+
|
|
27
|
+
return { start, end }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {import('jscodeshift').ObjectProperty} objectProperty
|
|
32
|
+
* @returns {boolean}
|
|
33
|
+
*/
|
|
34
|
+
const isKeepPreviousDataObjectProperty = (objectProperty) => {
|
|
35
|
+
return jscodeshift.match(objectProperty.key, {
|
|
36
|
+
type: jscodeshift.Identifier.name,
|
|
37
|
+
name: 'keepPreviousData',
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {import('jscodeshift').ObjectProperty} objectProperty
|
|
43
|
+
* @returns {boolean}
|
|
44
|
+
*/
|
|
45
|
+
const isObjectPropertyHasTrueBooleanLiteralValue = (objectProperty) => {
|
|
46
|
+
return jscodeshift.match(objectProperty.value, {
|
|
47
|
+
type: jscodeshift.BooleanLiteral.name,
|
|
48
|
+
value: true,
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {import('jscodeshift').ObjectExpression} objectExpression
|
|
54
|
+
* @returns {Array<import('jscodeshift').ObjectProperty>}
|
|
55
|
+
*/
|
|
56
|
+
const filterKeepPreviousDataProperty = (objectExpression) => {
|
|
57
|
+
return objectExpression.properties.filter((objectProperty) => {
|
|
58
|
+
return !isKeepPreviousDataObjectProperty(objectProperty)
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const createPlaceholderDataObjectProperty = () => {
|
|
63
|
+
return jscodeshift.objectProperty(
|
|
64
|
+
jscodeshift.identifier('placeholderData'),
|
|
65
|
+
jscodeshift.identifier('keepPreviousData'),
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @param {import('jscodeshift').ObjectExpression} objectExpression
|
|
71
|
+
* @returns {boolean}
|
|
72
|
+
*/
|
|
73
|
+
const hasPlaceholderDataProperty = (objectExpression) => {
|
|
74
|
+
return (
|
|
75
|
+
objectExpression.properties.findIndex((objectProperty) => {
|
|
76
|
+
return jscodeshift.match(objectProperty.key, {
|
|
77
|
+
type: jscodeshift.Identifier.name,
|
|
78
|
+
name: 'placeholderData',
|
|
79
|
+
})
|
|
80
|
+
}) !== -1
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param {import('jscodeshift').ObjectExpression} objectExpression
|
|
86
|
+
* @returns {import('jscodeshift').ObjectProperty | undefined}
|
|
87
|
+
*/
|
|
88
|
+
const getKeepPreviousDataProperty = (objectExpression) => {
|
|
89
|
+
return objectExpression.properties.find(isKeepPreviousDataObjectProperty)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let shouldAddKeepPreviousDataImport = false
|
|
93
|
+
|
|
94
|
+
const replacer = (path, resolveTargetArgument, transformNode) => {
|
|
95
|
+
const node = path.node
|
|
96
|
+
const { start, end } = getNodeLocation(node)
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
const targetArgument = resolveTargetArgument(node)
|
|
100
|
+
|
|
101
|
+
if (targetArgument && utils.isObjectExpression(targetArgument)) {
|
|
102
|
+
const isPlaceholderDataPropertyPresent =
|
|
103
|
+
hasPlaceholderDataProperty(targetArgument)
|
|
104
|
+
|
|
105
|
+
if (hasPlaceholderDataProperty(targetArgument)) {
|
|
106
|
+
throw new AlreadyHasPlaceholderDataProperty(node, filePath)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const keepPreviousDataProperty =
|
|
110
|
+
getKeepPreviousDataProperty(targetArgument)
|
|
111
|
+
|
|
112
|
+
const keepPreviousDataPropertyHasTrueValue =
|
|
113
|
+
isObjectPropertyHasTrueBooleanLiteralValue(keepPreviousDataProperty)
|
|
114
|
+
|
|
115
|
+
if (!keepPreviousDataPropertyHasTrueValue) {
|
|
116
|
+
utils.warn(
|
|
117
|
+
`The usage in file "${filePath}" at line ${start}:${end} already contains a "keepPreviousData" property but its value is not "true". Please migrate this usage manually.`,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
return node
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (keepPreviousDataPropertyHasTrueValue) {
|
|
124
|
+
// Removing the `keepPreviousData` property from the object.
|
|
125
|
+
const mutableObjectExpressionProperties =
|
|
126
|
+
filterKeepPreviousDataProperty(targetArgument)
|
|
127
|
+
|
|
128
|
+
if (!isPlaceholderDataPropertyPresent) {
|
|
129
|
+
shouldAddKeepPreviousDataImport = true
|
|
130
|
+
|
|
131
|
+
// When the `placeholderData` property is not present, the `placeholderData: keepPreviousData` property will be added.
|
|
132
|
+
mutableObjectExpressionProperties.push(
|
|
133
|
+
createPlaceholderDataObjectProperty(),
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return transformNode(
|
|
138
|
+
node,
|
|
139
|
+
jscodeshift.objectExpression(mutableObjectExpressionProperties),
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
utils.warn(
|
|
145
|
+
`The usage in file "${filePath}" at line ${start}:${end} could not be transformed, because the first parameter is not an object expression. Please migrate this usage manually.`,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
return node
|
|
149
|
+
} catch (error) {
|
|
150
|
+
utils.warn(
|
|
151
|
+
error.name === AlreadyHasPlaceholderDataProperty.name
|
|
152
|
+
? error.message
|
|
153
|
+
: `An unknown error occurred while processing the "${filePath}" file. Please review this file, because the codemod couldn't be applied.`,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
return node
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
createUseQueryLikeTransformer({ jscodeshift, utils, root }).execute(
|
|
161
|
+
config.hooks,
|
|
162
|
+
(path) => {
|
|
163
|
+
const resolveTargetArgument = (node) => node.arguments[0] ?? null
|
|
164
|
+
const transformNode = (node, transformedArgument) =>
|
|
165
|
+
jscodeshift.callExpression(node.original.callee, [transformedArgument])
|
|
166
|
+
|
|
167
|
+
return replacer(path, resolveTargetArgument, transformNode)
|
|
168
|
+
},
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
createQueryClientTransformer({ jscodeshift, utils, root }).execute(
|
|
172
|
+
config.queryClientMethods,
|
|
173
|
+
(path) => {
|
|
174
|
+
const resolveTargetArgument = (node) => node.arguments[1] ?? null
|
|
175
|
+
const transformNode = (node, transformedArgument) => {
|
|
176
|
+
return jscodeshift.callExpression(node.original.callee, [
|
|
177
|
+
node.arguments[0],
|
|
178
|
+
transformedArgument,
|
|
179
|
+
...node.arguments.slice(2, 0),
|
|
180
|
+
])
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return replacer(path, resolveTargetArgument, transformNode)
|
|
184
|
+
},
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
const importIdentifierOfQueryClient = utils.getSelectorByImports(
|
|
188
|
+
utils.locateImports(['QueryClient']),
|
|
189
|
+
'QueryClient',
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
root
|
|
193
|
+
.find(jscodeshift.ExpressionStatement, {
|
|
194
|
+
expression: {
|
|
195
|
+
type: jscodeshift.NewExpression.name,
|
|
196
|
+
callee: {
|
|
197
|
+
type: jscodeshift.Identifier.name,
|
|
198
|
+
name: importIdentifierOfQueryClient,
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
})
|
|
202
|
+
.filter((path) => path.node.expression)
|
|
203
|
+
.replaceWith((path) => {
|
|
204
|
+
const resolveTargetArgument = (node) => {
|
|
205
|
+
const paths = jscodeshift(node)
|
|
206
|
+
.find(jscodeshift.ObjectProperty, {
|
|
207
|
+
key: {
|
|
208
|
+
type: jscodeshift.Identifier.name,
|
|
209
|
+
name: 'keepPreviousData',
|
|
210
|
+
},
|
|
211
|
+
})
|
|
212
|
+
.paths()
|
|
213
|
+
|
|
214
|
+
return paths.length > 0 ? paths[0].parent.node : null
|
|
215
|
+
}
|
|
216
|
+
const transformNode = (node, transformedArgument) => {
|
|
217
|
+
jscodeshift(node.expression)
|
|
218
|
+
.find(jscodeshift.ObjectProperty, {
|
|
219
|
+
key: {
|
|
220
|
+
type: jscodeshift.Identifier.name,
|
|
221
|
+
name: 'queries',
|
|
222
|
+
},
|
|
223
|
+
})
|
|
224
|
+
.replaceWith(({ node: mutableNode }) => {
|
|
225
|
+
mutableNode.value.properties = transformedArgument.properties
|
|
226
|
+
|
|
227
|
+
return mutableNode
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
return node
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return replacer(path, resolveTargetArgument, transformNode)
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
return { shouldAddKeepPreviousDataImport }
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
module.exports = (file, api) => {
|
|
240
|
+
const jscodeshift = api.jscodeshift
|
|
241
|
+
const root = jscodeshift(file.source)
|
|
242
|
+
const utils = createUtilsObject({ root, jscodeshift })
|
|
243
|
+
const filePath = file.path
|
|
244
|
+
|
|
245
|
+
const dependencies = { jscodeshift, utils, root, filePath }
|
|
246
|
+
|
|
247
|
+
const { shouldAddKeepPreviousDataImport } = transformUsages({
|
|
248
|
+
...dependencies,
|
|
249
|
+
config: {
|
|
250
|
+
hooks: ['useInfiniteQuery', 'useQueries', 'useQuery'],
|
|
251
|
+
queryClientMethods: ['setQueryDefaults'],
|
|
252
|
+
},
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
if (shouldAddKeepPreviousDataImport) {
|
|
256
|
+
root
|
|
257
|
+
.find(jscodeshift.ImportDeclaration, {
|
|
258
|
+
source: {
|
|
259
|
+
value: '@tanstack/react-query',
|
|
260
|
+
},
|
|
261
|
+
})
|
|
262
|
+
.replaceWith(({ node: mutableNode }) => {
|
|
263
|
+
mutableNode.specifiers = [
|
|
264
|
+
jscodeshift.importSpecifier(
|
|
265
|
+
jscodeshift.identifier('keepPreviousData'),
|
|
266
|
+
),
|
|
267
|
+
...mutableNode.specifiers,
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
return mutableNode
|
|
271
|
+
})
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return root.toSource({ quote: 'single', lineTerminator: '\n' })
|
|
275
|
+
}
|
package/build/codemods/src/v5/keep-previous-data/utils/already-has-placeholder-data-property.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class AlreadyHasPlaceholderDataProperty extends Error {
|
|
2
|
+
/**
|
|
3
|
+
* @param {import('jscodeshift').CallExpression} callExpression
|
|
4
|
+
* @param {string} filePath
|
|
5
|
+
*/
|
|
6
|
+
constructor(callExpression, filePath) {
|
|
7
|
+
super('')
|
|
8
|
+
this.message = this.buildMessage(callExpression, filePath)
|
|
9
|
+
this.name = 'AlreadyHasPlaceholderDataProperty'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {import('jscodeshift').CallExpression} callExpression
|
|
14
|
+
* @param {string} filePath
|
|
15
|
+
* @returns {string}
|
|
16
|
+
*/
|
|
17
|
+
buildMessage(callExpression, filePath) {
|
|
18
|
+
const location = callExpression.callee.loc
|
|
19
|
+
const start = location.start.line
|
|
20
|
+
const end = location.end.line
|
|
21
|
+
|
|
22
|
+
return `The usage in file "${filePath}" at line ${start}:${end} already contains a a "placeholderData" property. Please migrate this usage manually.`
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = AlreadyHasPlaceholderDataProperty
|
|
@@ -42,6 +42,13 @@ var import_isRestoring = require("./isRestoring.cjs");
|
|
|
42
42
|
var import_errorBoundaryUtils = require("./errorBoundaryUtils.cjs");
|
|
43
43
|
var import_suspense = require("./suspense.cjs");
|
|
44
44
|
function useBaseQuery(options, Observer, queryClient) {
|
|
45
|
+
if (process.env.NODE_ENV !== "production") {
|
|
46
|
+
if (typeof options !== "object" || Array.isArray(options)) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
'Bad argument type. Starting with v5, only the "Object" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object'
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
45
52
|
const client = (0, import_QueryClientProvider.useQueryClient)(queryClient);
|
|
46
53
|
const isRestoring = (0, import_isRestoring.useIsRestoring)();
|
|
47
54
|
const errorResetBoundary = (0, import_QueryErrorResetBoundary.useQueryErrorResetBoundary)();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAEvB,wBAA8B;AAC9B,qCAA2C;AAC3C,iCAA+B;AAC/B,yBAA+B;AAC/B,gCAIO;AACP,sBAAgE;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,QAAM,aAAS,2CAAe,WAAW;AACzC,QAAM,kBAAc,mCAAe;AACnC,QAAM,yBAAqB,2DAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,uCAAgB,gBAAgB;AAChC,iEAAgC,kBAAkB,kBAAkB;AAEpE,4DAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,gCAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,UAAI,+BAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,cAAM,iCAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,UACE,uCAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n if (process.env.NODE_ENV !== 'production') {\n if (typeof options !== 'object' || Array.isArray(options)) {\n throw new Error(\n 'Bad argument type. Starting with v5, only the \"Object\" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object',\n )\n }\n }\n\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAEvB,wBAA8B;AAC9B,qCAA2C;AAC3C,iCAA+B;AAC/B,yBAA+B;AAC/B,gCAIO;AACP,sBAAgE;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,QAAI,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAAG;AACzD,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAS,2CAAe,WAAW;AACzC,QAAM,kBAAc,mCAAe;AACnC,QAAM,yBAAqB,2DAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,uCAAgB,gBAAgB;AAChC,iEAAgC,kBAAkB,kBAAkB;AAEpE,4DAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,gCAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,UAAI,+BAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,cAAM,iCAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,UACE,uCAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
|
@@ -13,6 +13,13 @@ import {
|
|
|
13
13
|
} from "./errorBoundaryUtils.js";
|
|
14
14
|
import { ensureStaleTime, fetchOptimistic, shouldSuspend } from "./suspense.js";
|
|
15
15
|
function useBaseQuery(options, Observer, queryClient) {
|
|
16
|
+
if (process.env.NODE_ENV !== "production") {
|
|
17
|
+
if (typeof options !== "object" || Array.isArray(options)) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
'Bad argument type. Starting with v5, only the "Object" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object'
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
16
23
|
const client = useQueryClient(queryClient);
|
|
17
24
|
const isRestoring = useIsRestoring();
|
|
18
25
|
const errorResetBoundary = useQueryErrorResetBoundary();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,qBAAqB;AAC9B,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB,iBAAiB,qBAAqB;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,kBAAgB,gBAAgB;AAChC,kCAAgC,kBAAkB,kBAAkB;AAEpE,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,MAAI,cAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,UAAM,gBAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,MACE,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n if (process.env.NODE_ENV !== 'production') {\n if (typeof options !== 'object' || Array.isArray(options)) {\n throw new Error(\n 'Bad argument type. Starting with v5, only the \"Object\" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object',\n )\n }\n }\n\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,qBAAqB;AAC9B,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB,iBAAiB,qBAAqB;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,QAAI,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAAG;AACzD,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,kBAAgB,gBAAgB;AAChC,kCAAgC,kBAAkB,kBAAkB;AAEpE,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,MAAI,cAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,UAAM,gBAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,MACE,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
|
@@ -42,6 +42,13 @@ var import_isRestoring = require("./isRestoring.cjs");
|
|
|
42
42
|
var import_errorBoundaryUtils = require("./errorBoundaryUtils.cjs");
|
|
43
43
|
var import_suspense = require("./suspense.cjs");
|
|
44
44
|
function useBaseQuery(options, Observer, queryClient) {
|
|
45
|
+
if (process.env.NODE_ENV !== "production") {
|
|
46
|
+
if (typeof options !== "object" || Array.isArray(options)) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
'Bad argument type. Starting with v5, only the "Object" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object'
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
45
52
|
const client = (0, import_QueryClientProvider.useQueryClient)(queryClient);
|
|
46
53
|
const isRestoring = (0, import_isRestoring.useIsRestoring)();
|
|
47
54
|
const errorResetBoundary = (0, import_QueryErrorResetBoundary.useQueryErrorResetBoundary)();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAEvB,wBAA8B;AAC9B,qCAA2C;AAC3C,iCAA+B;AAC/B,yBAA+B;AAC/B,gCAIO;AACP,sBAAgE;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,QAAM,aAAS,2CAAe,WAAW;AACzC,QAAM,kBAAc,mCAAe;AACnC,QAAM,yBAAqB,2DAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,uCAAgB,gBAAgB;AAChC,iEAAgC,kBAAkB,kBAAkB;AAEpE,4DAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,gCAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,UAAI,+BAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,cAAM,iCAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,UACE,uCAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n if (process.env.NODE_ENV !== 'production') {\n if (typeof options !== 'object' || Array.isArray(options)) {\n throw new Error(\n 'Bad argument type. Starting with v5, only the \"Object\" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object',\n )\n }\n }\n\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAEvB,wBAA8B;AAC9B,qCAA2C;AAC3C,iCAA+B;AAC/B,yBAA+B;AAC/B,gCAIO;AACP,sBAAgE;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,QAAI,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAAG;AACzD,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAS,2CAAe,WAAW;AACzC,QAAM,kBAAc,mCAAe;AACnC,QAAM,yBAAqB,2DAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,uCAAgB,gBAAgB;AAChC,iEAAgC,kBAAkB,kBAAkB;AAEpE,4DAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,gCAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,UAAI,+BAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,cAAM,iCAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,UACE,uCAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
|
@@ -13,6 +13,13 @@ import {
|
|
|
13
13
|
} from "./errorBoundaryUtils.js";
|
|
14
14
|
import { ensureStaleTime, fetchOptimistic, shouldSuspend } from "./suspense.js";
|
|
15
15
|
function useBaseQuery(options, Observer, queryClient) {
|
|
16
|
+
if (process.env.NODE_ENV !== "production") {
|
|
17
|
+
if (typeof options !== "object" || Array.isArray(options)) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
'Bad argument type. Starting with v5, only the "Object" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object'
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
16
23
|
const client = useQueryClient(queryClient);
|
|
17
24
|
const isRestoring = useIsRestoring();
|
|
18
25
|
const errorResetBoundary = useQueryErrorResetBoundary();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,qBAAqB;AAC9B,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB,iBAAiB,qBAAqB;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,kBAAgB,gBAAgB;AAChC,kCAAgC,kBAAkB,kBAAkB;AAEpE,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,MAAI,cAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,UAAM,gBAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,MACE,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/useBaseQuery.ts"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { notifyManager } from '@tanstack/query-core'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useIsRestoring } from './isRestoring'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'\nimport type { UseBaseQueryOptions } from './types'\nimport type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n) {\n if (process.env.NODE_ENV !== 'production') {\n if (typeof options !== 'object' || Array.isArray(options)) {\n throw new Error(\n 'Bad argument type. Starting with v5, only the \"Object\" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object',\n )\n }\n }\n\n const client = useQueryClient(queryClient)\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const defaultedOptions = client.defaultQueryOptions(options)\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureStaleTime(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary)\n\n useClearResetErrorBoundary(errorResetBoundary)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n const result = observer.getOptimisticResult(defaultedOptions)\n\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = isRestoring\n ? () => undefined\n : observer.subscribe(notifyManager.batchCalls(onStoreChange))\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, isRestoring],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n // Do not notify on updates because of changes in the options because\n // these changes should already be reflected in the optimistic result.\n observer.setOptions(defaultedOptions, { listeners: false })\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result, isRestoring)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query: observer.getCurrentQuery(),\n })\n ) {\n throw result.error\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,qBAAqB;AAC9B,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB,iBAAiB,qBAAqB;AAIzD,SAAS,aAOd,SAOA,UACA,aACA;AACA,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,QAAI,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAAG;AACzD,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,eAAe,WAAW;AACzC,QAAM,cAAc,eAAe;AACnC,QAAM,qBAAqB,2BAA2B;AACtD,QAAM,mBAAmB,OAAO,oBAAoB,OAAO;AAG3D,mBAAiB,qBAAqB,cAClC,gBACA;AAEJ,kBAAgB,gBAAgB;AAChC,kCAAgC,kBAAkB,kBAAkB;AAEpE,6BAA2B,kBAAkB;AAE7C,QAAM,CAAC,QAAQ,IAAU;AAAA,IACvB,MACE,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACJ;AAEA,QAAM,SAAS,SAAS,oBAAoB,gBAAgB;AAE5D,EAAM;AAAA,IACE;AAAA,MACJ,CAAC,kBAAkB;AACjB,cAAM,cAAc,cAChB,MAAM,SACN,SAAS,UAAU,cAAc,WAAW,aAAa,CAAC;AAI9D,iBAAS,aAAa;AAEtB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,WAAW;AAAA,IACxB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,MAAM,SAAS,iBAAiB;AAAA,EAClC;AAEA,EAAM,gBAAU,MAAM;AAGpB,aAAS,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5D,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAG/B,MAAI,cAAc,kBAAkB,QAAQ,WAAW,GAAG;AACxD,UAAM,gBAAgB,kBAAkB,UAAU,kBAAkB;AAAA,EACtE;AAGA,MACE,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,OAAO,SAAS,gBAAgB;AAAA,EAClC,CAAC,GACD;AACA,UAAM,OAAO;AAAA,EACf;AAGA,SAAO,CAAC,iBAAiB,sBACrB,SAAS,YAAY,MAAM,IAC3B;AACN;","names":[]}
|
package/package.json
CHANGED
|
@@ -6225,4 +6225,25 @@ describe('useQuery', () => {
|
|
|
6225
6225
|
|
|
6226
6226
|
await waitFor(() => rendered.getByText('Works'))
|
|
6227
6227
|
})
|
|
6228
|
+
|
|
6229
|
+
// For Project without TS, when migrating from v4 to v5, make sure invalid calls due to bad parameters are tracked.
|
|
6230
|
+
it('should throw in case of bad arguments to enhance DevX', async () => {
|
|
6231
|
+
// Mock console error to avoid noise when test is run
|
|
6232
|
+
const consoleMock = vi
|
|
6233
|
+
.spyOn(console, 'error')
|
|
6234
|
+
.mockImplementation(() => undefined)
|
|
6235
|
+
|
|
6236
|
+
const key = queryKey()
|
|
6237
|
+
const queryFn = () => 'data'
|
|
6238
|
+
|
|
6239
|
+
function Page() {
|
|
6240
|
+
// Invalid call on purpose
|
|
6241
|
+
// @ts-expect-error
|
|
6242
|
+
useQuery(key, { queryFn })
|
|
6243
|
+
return <div>Does not matter</div>
|
|
6244
|
+
}
|
|
6245
|
+
|
|
6246
|
+
expect(() => render(<Page />)).toThrow('Bad argument type')
|
|
6247
|
+
consoleMock.mockRestore()
|
|
6248
|
+
})
|
|
6228
6249
|
})
|
package/src/useBaseQuery.ts
CHANGED
|
@@ -31,6 +31,14 @@ export function useBaseQuery<
|
|
|
31
31
|
Observer: typeof QueryObserver,
|
|
32
32
|
queryClient?: QueryClient,
|
|
33
33
|
) {
|
|
34
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
35
|
+
if (typeof options !== 'object' || Array.isArray(options)) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
'Bad argument type. Starting with v5, only the "Object" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object',
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
34
42
|
const client = useQueryClient(queryClient)
|
|
35
43
|
const isRestoring = useIsRestoring()
|
|
36
44
|
const errorResetBoundary = useQueryErrorResetBoundary()
|