@tanstack/solid-query 4.4.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.
Files changed (108) hide show
  1. package/build/lib/QueryClientProvider.d.ts +24 -0
  2. package/build/lib/QueryClientProvider.esm.js +68 -0
  3. package/build/lib/QueryClientProvider.esm.js.map +1 -0
  4. package/build/lib/QueryClientProvider.js +74 -0
  5. package/build/lib/QueryClientProvider.js.map +1 -0
  6. package/build/lib/QueryClientProvider.mjs +68 -0
  7. package/build/lib/QueryClientProvider.mjs.map +1 -0
  8. package/build/lib/createBaseQuery.d.ts +4 -0
  9. package/build/lib/createBaseQuery.esm.js +77 -0
  10. package/build/lib/createBaseQuery.esm.js.map +1 -0
  11. package/build/lib/createBaseQuery.js +81 -0
  12. package/build/lib/createBaseQuery.js.map +1 -0
  13. package/build/lib/createBaseQuery.mjs +77 -0
  14. package/build/lib/createBaseQuery.mjs.map +1 -0
  15. package/build/lib/createInfiniteQuery.d.ts +5 -0
  16. package/build/lib/createInfiniteQuery.esm.js +20 -0
  17. package/build/lib/createInfiniteQuery.esm.js.map +1 -0
  18. package/build/lib/createInfiniteQuery.js +24 -0
  19. package/build/lib/createInfiniteQuery.js.map +1 -0
  20. package/build/lib/createInfiniteQuery.mjs +20 -0
  21. package/build/lib/createInfiniteQuery.mjs.map +1 -0
  22. package/build/lib/createMutation.d.ts +6 -0
  23. package/build/lib/createMutation.esm.js +45 -0
  24. package/build/lib/createMutation.esm.js.map +1 -0
  25. package/build/lib/createMutation.js +49 -0
  26. package/build/lib/createMutation.js.map +1 -0
  27. package/build/lib/createMutation.mjs +45 -0
  28. package/build/lib/createMutation.mjs.map +1 -0
  29. package/build/lib/createQueries.d.ts +49 -0
  30. package/build/lib/createQueries.esm.js +54 -0
  31. package/build/lib/createQueries.esm.js.map +1 -0
  32. package/build/lib/createQueries.js +58 -0
  33. package/build/lib/createQueries.js.map +1 -0
  34. package/build/lib/createQueries.mjs +54 -0
  35. package/build/lib/createQueries.mjs.map +1 -0
  36. package/build/lib/createQuery.d.ts +23 -0
  37. package/build/lib/createQuery.esm.js +25 -0
  38. package/build/lib/createQuery.esm.js.map +1 -0
  39. package/build/lib/createQuery.js +29 -0
  40. package/build/lib/createQuery.js.map +1 -0
  41. package/build/lib/createQuery.mjs +25 -0
  42. package/build/lib/createQuery.mjs.map +1 -0
  43. package/build/lib/index.d.ts +10 -0
  44. package/build/lib/index.esm.js +9 -0
  45. package/build/lib/index.esm.js.map +1 -0
  46. package/build/lib/index.js +31 -0
  47. package/build/lib/index.js.map +1 -0
  48. package/build/lib/index.mjs +9 -0
  49. package/build/lib/index.mjs.map +1 -0
  50. package/build/lib/types.d.ts +47 -0
  51. package/build/lib/useIsFetching.d.ts +7 -0
  52. package/build/lib/useIsFetching.esm.js +29 -0
  53. package/build/lib/useIsFetching.esm.js.map +1 -0
  54. package/build/lib/useIsFetching.js +33 -0
  55. package/build/lib/useIsFetching.js.map +1 -0
  56. package/build/lib/useIsFetching.mjs +29 -0
  57. package/build/lib/useIsFetching.mjs.map +1 -0
  58. package/build/lib/useIsMutating.d.ts +8 -0
  59. package/build/lib/useIsMutating.esm.js +22 -0
  60. package/build/lib/useIsMutating.esm.js.map +1 -0
  61. package/build/lib/useIsMutating.js +26 -0
  62. package/build/lib/useIsMutating.js.map +1 -0
  63. package/build/lib/useIsMutating.mjs +22 -0
  64. package/build/lib/useIsMutating.mjs.map +1 -0
  65. package/build/lib/utils.d.ts +14 -0
  66. package/build/lib/utils.esm.js +63 -0
  67. package/build/lib/utils.esm.js.map +1 -0
  68. package/build/lib/utils.js +72 -0
  69. package/build/lib/utils.js.map +1 -0
  70. package/build/lib/utils.mjs +63 -0
  71. package/build/lib/utils.mjs.map +1 -0
  72. package/build/solid/QueryClientProvider.jsx +42 -0
  73. package/build/solid/createBaseQuery.js +69 -0
  74. package/build/solid/createInfiniteQuery.js +16 -0
  75. package/build/solid/createMutation.js +40 -0
  76. package/build/solid/createQueries.js +39 -0
  77. package/build/solid/createQuery.js +16 -0
  78. package/build/solid/index.js +11 -0
  79. package/build/solid/types.js +1 -0
  80. package/build/solid/useIsFetching.js +23 -0
  81. package/build/solid/useIsMutating.js +16 -0
  82. package/build/solid/utils.js +45 -0
  83. package/build/umd/index.development.js +3467 -0
  84. package/build/umd/index.development.js.map +1 -0
  85. package/build/umd/index.production.js +2 -0
  86. package/build/umd/index.production.js.map +1 -0
  87. package/package.json +52 -0
  88. package/src/QueryClientProvider.tsx +100 -0
  89. package/src/__tests__/QueryClientProvider.test.tsx +267 -0
  90. package/src/__tests__/createInfiniteQuery.test.tsx +1889 -0
  91. package/src/__tests__/createMutation.test.tsx +1205 -0
  92. package/src/__tests__/createQueries.test.tsx +1163 -0
  93. package/src/__tests__/createQuery.test.tsx +6487 -0
  94. package/src/__tests__/createQuery.types.test.tsx +160 -0
  95. package/src/__tests__/suspense.test.tsx +1093 -0
  96. package/src/__tests__/useIsFetching.test.tsx +298 -0
  97. package/src/__tests__/useIsMutating.test.tsx +301 -0
  98. package/src/__tests__/utils.tsx +75 -0
  99. package/src/createBaseQuery.ts +121 -0
  100. package/src/createInfiniteQuery.ts +116 -0
  101. package/src/createMutation.ts +131 -0
  102. package/src/createQueries.ts +203 -0
  103. package/src/createQuery.ts +157 -0
  104. package/src/index.ts +17 -0
  105. package/src/types.ts +167 -0
  106. package/src/useIsFetching.ts +58 -0
  107. package/src/useIsMutating.ts +42 -0
  108. package/src/utils.ts +85 -0
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@tanstack/solid-query",
3
+ "version": "4.4.0",
4
+ "description": "Primitives for managing, caching and syncing asynchronous and remote data in Solid",
5
+ "author": "tannerlinsley",
6
+ "license": "MIT",
7
+ "repository": "tanstack/query",
8
+ "homepage": "https://tanstack.com/query",
9
+ "funding": {
10
+ "type": "github",
11
+ "url": "https://github.com/sponsors/tannerlinsley"
12
+ },
13
+ "types": "build/lib/index.d.ts",
14
+ "main": "build/lib/index.js",
15
+ "module": "build/lib/index.esm.js",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./build/lib/index.d.ts",
19
+ "solid": "./build/solid/index.js",
20
+ "import": "./build/lib/index.mjs",
21
+ "browser": "./build/lib/index.mjs",
22
+ "require": "./build/lib/index.js",
23
+ "node": "./build/lib/index.js",
24
+ "default": "./build/lib/index.js"
25
+ },
26
+ "./package.json": "./package.json"
27
+ },
28
+ "sideEffects": false,
29
+ "scripts": {
30
+ "clean": "rm -rf ./build",
31
+ "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src",
32
+ "test:jest": "../../node_modules/.bin/jest --config jest.config.js",
33
+ "test:jest:dev": "yarn test:jest --watch"
34
+ },
35
+ "files": [
36
+ "build/lib/*",
37
+ "build/umd/*",
38
+ "build/solid/*",
39
+ "src"
40
+ ],
41
+ "devDependencies": {
42
+ "@types/jscodeshift": "^0.11.3",
43
+ "jscodeshift": "^0.13.1"
44
+ },
45
+ "dependencies": {
46
+ "@tanstack/query-core": "4.4.0"
47
+ },
48
+ "peerDependencies": {
49
+ "solid-js": "^1.5.4"
50
+ },
51
+ "peerDependenciesMeta": {}
52
+ }
@@ -0,0 +1,100 @@
1
+ import type { QueryClient } from '@tanstack/query-core'
2
+ import type { Context, JSX } from 'solid-js'
3
+ import {
4
+ createContext,
5
+ useContext,
6
+ onMount,
7
+ onCleanup,
8
+ mergeProps,
9
+ } from 'solid-js'
10
+ import type { ContextOptions } from './types'
11
+
12
+ declare global {
13
+ interface Window {
14
+ SolidQueryClientContext?: Context<QueryClient | undefined>
15
+ }
16
+ }
17
+
18
+ export const defaultContext = createContext<QueryClient | undefined>(undefined)
19
+ const QueryClientSharingContext = createContext<boolean>(false)
20
+
21
+ // If we are given a context, we will use it.
22
+ // Otherwise, if contextSharing is on, we share the first and at least one
23
+ // instance of the context across the window
24
+ // to ensure that if Solid Query is used across
25
+ // different bundles or microfrontends they will
26
+ // all use the same **instance** of context, regardless
27
+ // of module scoping.
28
+ function getQueryClientContext(
29
+ context: Context<QueryClient | undefined> | undefined,
30
+ contextSharing: boolean,
31
+ ) {
32
+ if (context) {
33
+ return context
34
+ }
35
+ if (contextSharing && typeof window !== 'undefined') {
36
+ if (!window.SolidQueryClientContext) {
37
+ window.SolidQueryClientContext = defaultContext
38
+ }
39
+
40
+ return window.SolidQueryClientContext
41
+ }
42
+
43
+ return defaultContext
44
+ }
45
+
46
+ export const useQueryClient = ({ context }: ContextOptions = {}) => {
47
+ const queryClient = useContext(
48
+ getQueryClientContext(context, useContext(QueryClientSharingContext)),
49
+ )
50
+
51
+ if (!queryClient) {
52
+ throw new Error('No QueryClient set, use QueryClientProvider to set one')
53
+ }
54
+
55
+ return queryClient
56
+ }
57
+
58
+ type QueryClientProviderPropsBase = {
59
+ client: QueryClient
60
+ children?: JSX.Element
61
+ }
62
+ type QueryClientProviderPropsWithContext = ContextOptions & {
63
+ contextSharing?: never
64
+ } & QueryClientProviderPropsBase
65
+ type QueryClientProviderPropsWithContextSharing = {
66
+ context?: never
67
+ contextSharing?: boolean
68
+ } & QueryClientProviderPropsBase
69
+
70
+ export type QueryClientProviderProps =
71
+ | QueryClientProviderPropsWithContext
72
+ | QueryClientProviderPropsWithContextSharing
73
+
74
+ export const QueryClientProvider = (
75
+ props: QueryClientProviderProps,
76
+ ): JSX.Element => {
77
+ const mergedProps = mergeProps(
78
+ {
79
+ contextSharing: false,
80
+ },
81
+ props,
82
+ )
83
+ onMount(() => mergedProps.client.mount())
84
+ onCleanup(() => mergedProps.client.unmount())
85
+
86
+ const QueryClientContext = getQueryClientContext(
87
+ mergedProps.context,
88
+ mergedProps.contextSharing,
89
+ )
90
+
91
+ return (
92
+ <QueryClientSharingContext.Provider
93
+ value={!mergedProps.context && mergedProps.contextSharing}
94
+ >
95
+ <QueryClientContext.Provider value={mergedProps.client}>
96
+ {mergedProps.children}
97
+ </QueryClientContext.Provider>
98
+ </QueryClientSharingContext.Provider>
99
+ )
100
+ }
@@ -0,0 +1,267 @@
1
+ import { render, screen, waitFor } from 'solid-testing-library'
2
+ import { queryKey } from './utils'
3
+
4
+ import { QueryCache, QueryClient } from '@tanstack/query-core'
5
+ import type { Context } from 'solid-js'
6
+ import { createContext, useContext } from 'solid-js'
7
+ import { renderToString } from 'solid-js/web'
8
+ import { createQuery, QueryClientProvider, useQueryClient } from '..'
9
+ import { createQueryClient, sleep } from './utils'
10
+
11
+ describe('QueryClientProvider', () => {
12
+ it('sets a specific cache for all queries to use', async () => {
13
+ const key = queryKey()
14
+
15
+ const queryCache = new QueryCache()
16
+ const queryClient = createQueryClient({ queryCache })
17
+
18
+ function Page() {
19
+ const query = createQuery(key, async () => {
20
+ await sleep(10)
21
+ return 'test'
22
+ })
23
+
24
+ return (
25
+ <div>
26
+ <h1>{query.data}</h1>
27
+ </div>
28
+ )
29
+ }
30
+
31
+ render(() => (
32
+ <QueryClientProvider client={queryClient}>
33
+ <Page />
34
+ </QueryClientProvider>
35
+ ))
36
+
37
+ await waitFor(() => {
38
+ return screen.getByText('test')
39
+ })
40
+
41
+ expect(queryCache.find(key())).toBeDefined()
42
+ })
43
+
44
+ it('allows multiple caches to be partitioned', async () => {
45
+ const key1 = queryKey()
46
+ const key2 = queryKey()
47
+
48
+ const queryCache1 = new QueryCache()
49
+ const queryCache2 = new QueryCache()
50
+
51
+ const queryClient1 = createQueryClient({ queryCache: queryCache1 })
52
+ const queryClient2 = createQueryClient({ queryCache: queryCache2 })
53
+
54
+ function Page1() {
55
+ const query = createQuery(key1, async () => {
56
+ await sleep(10)
57
+ return 'test1'
58
+ })
59
+
60
+ return (
61
+ <div>
62
+ <h1>{query.data}</h1>
63
+ </div>
64
+ )
65
+ }
66
+ function Page2() {
67
+ const query = createQuery(key2, async () => {
68
+ await sleep(10)
69
+ return 'test2'
70
+ })
71
+
72
+ return (
73
+ <div>
74
+ <h1>{query.data}</h1>
75
+ </div>
76
+ )
77
+ }
78
+
79
+ render(() => (
80
+ <>
81
+ <QueryClientProvider client={queryClient1}>
82
+ <Page1 />
83
+ </QueryClientProvider>
84
+ <QueryClientProvider client={queryClient2}>
85
+ <Page2 />
86
+ </QueryClientProvider>
87
+ </>
88
+ ))
89
+
90
+ await waitFor(() => screen.getByText('test1'))
91
+ await waitFor(() => screen.getByText('test2'))
92
+
93
+ expect(queryCache1.find(key1())).toBeDefined()
94
+ expect(queryCache1.find(key2())).not.toBeDefined()
95
+ expect(queryCache2.find(key1())).not.toBeDefined()
96
+ expect(queryCache2.find(key2())).toBeDefined()
97
+ })
98
+
99
+ it("uses defaultOptions for queries when they don't provide their own config", async () => {
100
+ const key = queryKey()
101
+
102
+ const queryCache = new QueryCache()
103
+ const queryClient = createQueryClient({
104
+ queryCache,
105
+ defaultOptions: {
106
+ queries: {
107
+ cacheTime: Infinity,
108
+ },
109
+ },
110
+ })
111
+
112
+ function Page() {
113
+ const query = createQuery(key, async () => {
114
+ await sleep(10)
115
+ return 'test'
116
+ })
117
+
118
+ return (
119
+ <div>
120
+ <h1>{query.data}</h1>
121
+ </div>
122
+ )
123
+ }
124
+
125
+ render(() => (
126
+ <QueryClientProvider client={queryClient}>
127
+ <Page />
128
+ </QueryClientProvider>
129
+ ))
130
+
131
+ await waitFor(() => screen.getByText('test'))
132
+
133
+ expect(queryCache.find(key())).toBeDefined()
134
+ expect(queryCache.find(key())?.options.cacheTime).toBe(Infinity)
135
+ })
136
+
137
+ describe('with custom context', () => {
138
+ it('uses the correct context', async () => {
139
+ const key = queryKey()
140
+
141
+ const contextOuter = createContext<QueryClient | undefined>(undefined)
142
+ const contextInner = createContext<QueryClient | undefined>(undefined)
143
+
144
+ const queryCacheOuter = new QueryCache()
145
+ const queryClientOuter = new QueryClient({ queryCache: queryCacheOuter })
146
+
147
+ const queryCacheInner = new QueryCache()
148
+ const queryClientInner = new QueryClient({ queryCache: queryCacheInner })
149
+
150
+ const queryCacheInnerInner = new QueryCache()
151
+ const queryClientInnerInner = new QueryClient({
152
+ queryCache: queryCacheInnerInner,
153
+ })
154
+
155
+ function Page() {
156
+ const queryOuter = createQuery(key, async () => 'testOuter', {
157
+ context: contextOuter,
158
+ })
159
+ const queryInner = createQuery(key, async () => 'testInner', {
160
+ context: contextInner,
161
+ })
162
+ const queryInnerInner = createQuery(key, async () => 'testInnerInner')
163
+
164
+ return (
165
+ <div>
166
+ <h1>
167
+ {queryOuter.data} {queryInner.data} {queryInnerInner.data}
168
+ </h1>
169
+ </div>
170
+ )
171
+ }
172
+
173
+ // contextSharing should be ignored when passing a custom context.
174
+ const contextSharing = true
175
+
176
+ render(() => (
177
+ <QueryClientProvider client={queryClientOuter} context={contextOuter}>
178
+ <QueryClientProvider client={queryClientInner} context={contextInner}>
179
+ <QueryClientProvider
180
+ client={queryClientInnerInner}
181
+ contextSharing={contextSharing}
182
+ >
183
+ <Page />
184
+ </QueryClientProvider>
185
+ </QueryClientProvider>
186
+ </QueryClientProvider>
187
+ ))
188
+
189
+ await waitFor(() =>
190
+ screen.getByText('testOuter testInner testInnerInner'),
191
+ )
192
+ })
193
+ })
194
+
195
+ describe('useQueryClient', () => {
196
+ it('should throw an error if no query client has been set', () => {
197
+ const consoleMock = jest
198
+ .spyOn(console, 'error')
199
+ .mockImplementation(() => undefined)
200
+
201
+ function Page() {
202
+ useQueryClient()
203
+ return null
204
+ }
205
+
206
+ expect(() => render(() => <Page />)).toThrow(
207
+ 'No QueryClient set, use QueryClientProvider to set one',
208
+ )
209
+
210
+ consoleMock.mockRestore()
211
+ })
212
+
213
+ it('should use window to get the context when contextSharing is true', () => {
214
+ const queryCache = new QueryCache()
215
+ const queryClient = createQueryClient({ queryCache })
216
+
217
+ let queryClientFromHook: QueryClient | undefined
218
+ let queryClientFromWindow: QueryClient | undefined
219
+
220
+ function Page() {
221
+ queryClientFromHook = useQueryClient()
222
+ queryClientFromWindow = useContext(
223
+ window.SolidQueryClientContext as Context<QueryClient | undefined>,
224
+ )
225
+ return null
226
+ }
227
+
228
+ render(() => (
229
+ <QueryClientProvider client={queryClient} contextSharing={true}>
230
+ <Page />
231
+ </QueryClientProvider>
232
+ ))
233
+
234
+ expect(queryClientFromHook).toEqual(queryClient)
235
+ expect(queryClientFromWindow).toEqual(queryClient)
236
+ })
237
+
238
+ it.skip('should not use window to get the context when contextSharing is true and window does not exist', () => {
239
+ const queryCache = new QueryCache()
240
+ const queryClient = createQueryClient({ queryCache })
241
+
242
+ // Mock a non web browser environment
243
+ const windowSpy = jest
244
+ .spyOn(window, 'window', 'get')
245
+ .mockImplementation(undefined)
246
+
247
+ let queryClientFromHook: QueryClient | undefined
248
+
249
+ function Page() {
250
+ queryClientFromHook = useQueryClient()
251
+ return null
252
+ }
253
+
254
+ // TODO(lukemurray): fails because renderToString never calls Page
255
+ // probably an SSR-testing issue we need to fix.
256
+ renderToString(() => (
257
+ <QueryClientProvider client={queryClient} contextSharing={true}>
258
+ <Page />
259
+ </QueryClientProvider>
260
+ ))
261
+
262
+ expect(queryClientFromHook).toEqual(queryClient)
263
+
264
+ windowSpy.mockRestore()
265
+ })
266
+ })
267
+ })