@tanstack/svelte-query 4.24.10 → 5.0.0-alpha.1

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 (46) hide show
  1. package/build/lib/{Hydrate.svelte → HydrationBoundary.svelte} +2 -1
  2. package/build/lib/HydrationBoundary.svelte.d.ts +21 -0
  3. package/build/lib/createBaseQuery.d.ts +3 -3
  4. package/build/lib/createBaseQuery.js +26 -22
  5. package/build/lib/createInfiniteQuery.d.ts +3 -5
  6. package/build/lib/createInfiniteQuery.js +5 -4
  7. package/build/lib/createMutation.d.ts +3 -6
  8. package/build/lib/createMutation.js +9 -9
  9. package/build/lib/createQueries.d.ts +12 -7
  10. package/build/lib/createQueries.js +12 -12
  11. package/build/lib/createQuery.d.ts +10 -22
  12. package/build/lib/createQuery.js +3 -5
  13. package/build/lib/index.d.ts +1 -1
  14. package/build/lib/index.js +1 -1
  15. package/build/lib/types.d.ts +16 -15
  16. package/build/lib/useHydrate.d.ts +2 -2
  17. package/build/lib/useHydrate.js +2 -2
  18. package/build/lib/useIsFetching.d.ts +2 -3
  19. package/build/lib/useIsFetching.js +3 -4
  20. package/build/lib/useIsMutating.d.ts +2 -3
  21. package/build/lib/useIsMutating.js +3 -4
  22. package/build/lib/useQueryClient.d.ts +1 -1
  23. package/build/lib/useQueryClient.js +6 -3
  24. package/build/lib/utils.d.ts +3 -0
  25. package/build/lib/utils.js +3 -0
  26. package/package.json +2 -2
  27. package/src/HydrationBoundary.svelte +16 -0
  28. package/src/__tests__/CreateQueries.svelte +5 -3
  29. package/src/__tests__/CreateQuery.svelte +14 -3
  30. package/src/__tests__/createQueries.test.ts +26 -22
  31. package/src/__tests__/createQuery.test.ts +36 -0
  32. package/src/__tests__/utils.ts +2 -34
  33. package/src/createBaseQuery.ts +47 -42
  34. package/src/createInfiniteQuery.ts +19 -81
  35. package/src/createMutation.ts +17 -72
  36. package/src/createQueries.ts +36 -27
  37. package/src/createQuery.ts +33 -107
  38. package/src/index.ts +1 -1
  39. package/src/types.ts +23 -16
  40. package/src/useHydrate.ts +6 -2
  41. package/src/useIsFetching.ts +2 -11
  42. package/src/useIsMutating.ts +3 -12
  43. package/src/useQueryClient.ts +8 -3
  44. package/src/utils.ts +8 -0
  45. package/build/lib/Hydrate.svelte.d.ts +0 -20
  46. package/src/Hydrate.svelte +0 -11
@@ -1,37 +1,41 @@
1
1
  import { describe, it, expect } from 'vitest'
2
- import { render, screen } from '@testing-library/svelte'
2
+ import { render, waitFor } from '@testing-library/svelte'
3
3
  import CreateQueries from './CreateQueries.svelte'
4
4
  import { sleep } from './utils'
5
5
 
6
6
  describe('createQueries', () => {
7
7
  it('Render and wait for success', async () => {
8
- render(CreateQueries, {
8
+ const rendered = render(CreateQueries, {
9
9
  props: {
10
- options: [
11
- {
12
- queryKey: ['key-1'],
13
- queryFn: async () => {
14
- await sleep(10)
15
- return 'Success 1'
10
+ options: {
11
+ queries: [
12
+ {
13
+ queryKey: ['key-1'],
14
+ queryFn: async () => {
15
+ await sleep(10)
16
+ return 'Success 1'
17
+ },
16
18
  },
17
- },
18
- {
19
- queryKey: ['key-2'],
20
- queryFn: async () => {
21
- await sleep(10)
22
- return 'Success 2'
19
+ {
20
+ queryKey: ['key-2'],
21
+ queryFn: async () => {
22
+ await sleep(10)
23
+ return 'Success 2'
24
+ },
23
25
  },
24
- },
25
- ],
26
+ ],
27
+ },
26
28
  },
27
29
  })
28
30
 
29
- expect(screen.queryByText('Success 1')).not.toBeInTheDocument()
30
- expect(screen.queryByText('Success 2')).not.toBeInTheDocument()
31
-
32
- await sleep(20)
31
+ await waitFor(() => {
32
+ expect(rendered.getByText('Loading 1')).toBeInTheDocument()
33
+ expect(rendered.getByText('Loading 2')).toBeInTheDocument()
34
+ })
33
35
 
34
- expect(screen.queryByText('Success 1')).toBeInTheDocument()
35
- expect(screen.queryByText('Success 2')).toBeInTheDocument()
36
+ await waitFor(() => {
37
+ expect(rendered.getByText('Success 1')).toBeInTheDocument()
38
+ expect(rendered.getByText('Success 2')).toBeInTheDocument()
39
+ })
36
40
  })
37
41
  })
@@ -1,7 +1,9 @@
1
1
  import { describe, it, expect } from 'vitest'
2
2
  import { render, waitFor } from '@testing-library/svelte'
3
+ import { writable } from 'svelte/store'
3
4
  import CreateQuery from './CreateQuery.svelte'
4
5
  import { sleep } from './utils'
6
+ import type { CreateQueryOptions, WritableOrVal } from '../types'
5
7
 
6
8
  describe('createQuery', () => {
7
9
  it('Render and wait for success', async () => {
@@ -25,4 +27,38 @@ describe('createQuery', () => {
25
27
  expect(rendered.getByText('Success')).toBeInTheDocument()
26
28
  })
27
29
  })
30
+
31
+ it('should keep previous data when returned as placeholder data', async () => {
32
+ const options: WritableOrVal<CreateQueryOptions> = writable({
33
+ queryKey: ['test', [1]],
34
+ queryFn: async ({ queryKey }) => {
35
+ await sleep(50)
36
+ const ids = queryKey[1]
37
+ if (!ids || !Array.isArray(ids)) return []
38
+ return ids.map((id) => ({ id }))
39
+ },
40
+ placeholderData: (previousData: { id: number }[]) => previousData,
41
+ })
42
+ const rendered = render(CreateQuery, { props: { options } })
43
+
44
+ expect(rendered.queryByText('id: 1')).not.toBeInTheDocument()
45
+ expect(rendered.queryByText('id: 2')).not.toBeInTheDocument()
46
+
47
+ await sleep(100)
48
+
49
+ expect(rendered.queryByText('id: 1')).toBeInTheDocument()
50
+ expect(rendered.queryByText('id: 2')).not.toBeInTheDocument()
51
+
52
+ options.update((o) => ({ ...o, queryKey: ['test', [1, 2]] }))
53
+
54
+ await sleep(0)
55
+
56
+ expect(rendered.queryByText('id: 1')).toBeInTheDocument()
57
+ expect(rendered.queryByText('id: 2')).not.toBeInTheDocument()
58
+
59
+ await sleep(100)
60
+
61
+ expect(rendered.queryByText('id: 1')).toBeInTheDocument()
62
+ expect(rendered.queryByText('id: 2')).toBeInTheDocument()
63
+ })
28
64
  })
@@ -1,14 +1,9 @@
1
1
  import { vi } from 'vitest'
2
2
  import { act } from '@testing-library/svelte'
3
- import {
4
- QueryClient,
5
- type QueryClientConfig,
6
- type MutationOptions,
7
- } from '../index'
3
+ import { QueryClient, type QueryClientConfig } from '../index'
8
4
 
9
5
  export function createQueryClient(config?: QueryClientConfig): QueryClient {
10
- vi.spyOn(console, 'error').mockImplementation(() => undefined)
11
- return new QueryClient({ logger: mockLogger, ...config })
6
+ return new QueryClient(config)
12
7
  }
13
8
 
14
9
  export function mockVisibilityState(value: DocumentVisibilityState) {
@@ -19,12 +14,6 @@ export function mockNavigatorOnLine(value: boolean) {
19
14
  return vi.spyOn(navigator, 'onLine', 'get').mockReturnValue(value)
20
15
  }
21
16
 
22
- export const mockLogger = {
23
- log: vi.fn(),
24
- warn: vi.fn(),
25
- error: vi.fn(),
26
- }
27
-
28
17
  let queryKeyCount = 0
29
18
  export function queryKey(): Array<string> {
30
19
  queryKeyCount++
@@ -49,24 +38,3 @@ export function setActTimeout(fn: () => void, ms?: number) {
49
38
  })
50
39
  }, ms)
51
40
  }
52
-
53
- /**
54
- * Assert the parameter is of a specific type.
55
- */
56
- export function expectType<T>(_: T): void {
57
- return undefined
58
- }
59
-
60
- /**
61
- * Assert the parameter is not typed as `any`
62
- */
63
- export function expectTypeNotAny<T>(_: 0 extends 1 & T ? never : T): void {
64
- return undefined
65
- }
66
-
67
- export function executeMutation(
68
- queryClient: QueryClient,
69
- options: MutationOptions<any, any, any, any>,
70
- ): Promise<unknown> {
71
- return queryClient.getMutationCache().build(queryClient, options).execute()
72
- }
@@ -1,11 +1,13 @@
1
- import {
2
- notifyManager,
3
- type QueryKey,
4
- type QueryObserver,
5
- } from '@tanstack/query-core'
6
- import type { CreateBaseQueryOptions, CreateBaseQueryResult } from './types'
1
+ import type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'
2
+ import { notifyManager } from '@tanstack/query-core'
3
+ import type {
4
+ CreateBaseQueryOptions,
5
+ CreateBaseQueryResult,
6
+ WritableOrVal,
7
+ } from './types'
7
8
  import { useQueryClient } from './useQueryClient'
8
- import { derived, readable } from 'svelte/store'
9
+ import { derived, get, readable, writable } from 'svelte/store'
10
+ import { isWritable } from './utils'
9
11
 
10
12
  export function createBaseQuery<
11
13
  TQueryFnData,
@@ -14,51 +16,54 @@ export function createBaseQuery<
14
16
  TQueryData,
15
17
  TQueryKey extends QueryKey,
16
18
  >(
17
- options: CreateBaseQueryOptions<
18
- TQueryFnData,
19
- TError,
20
- TData,
21
- TQueryData,
22
- TQueryKey
19
+ options: WritableOrVal<
20
+ CreateBaseQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
23
21
  >,
24
22
  Observer: typeof QueryObserver,
23
+ queryClient?: QueryClient,
25
24
  ): CreateBaseQueryResult<TData, TError> {
26
- const queryClient = useQueryClient()
27
- const defaultedOptions = queryClient.defaultQueryOptions(options)
28
- defaultedOptions._optimisticResults = 'optimistic'
25
+ const client = useQueryClient(queryClient)
26
+
27
+ const optionsStore = isWritable(options) ? options : writable(options)
28
+
29
+ const defaultedOptionsStore = derived(optionsStore, ($options) => {
30
+ const defaultedOptions = client.defaultQueryOptions($options)
31
+ defaultedOptions._optimisticResults = 'optimistic'
32
+
33
+ // Include callbacks in batch renders
34
+ if (defaultedOptions.onError) {
35
+ defaultedOptions.onError = notifyManager.batchCalls(
36
+ defaultedOptions.onError,
37
+ )
38
+ }
29
39
 
30
- let observer = new Observer<
40
+ if (defaultedOptions.onSuccess) {
41
+ defaultedOptions.onSuccess = notifyManager.batchCalls(
42
+ defaultedOptions.onSuccess,
43
+ )
44
+ }
45
+
46
+ if (defaultedOptions.onSettled) {
47
+ defaultedOptions.onSettled = notifyManager.batchCalls(
48
+ defaultedOptions.onSettled,
49
+ )
50
+ }
51
+
52
+ return defaultedOptions
53
+ })
54
+
55
+ const observer = new Observer<
31
56
  TQueryFnData,
32
57
  TError,
33
58
  TData,
34
59
  TQueryData,
35
60
  TQueryKey
36
- >(queryClient, defaultedOptions)
37
-
38
- // Include callbacks in batch renders
39
- if (defaultedOptions.onError) {
40
- defaultedOptions.onError = notifyManager.batchCalls(
41
- defaultedOptions.onError,
42
- )
43
- }
44
-
45
- if (defaultedOptions.onSuccess) {
46
- defaultedOptions.onSuccess = notifyManager.batchCalls(
47
- defaultedOptions.onSuccess,
48
- )
49
- }
50
-
51
- if (defaultedOptions.onSettled) {
52
- defaultedOptions.onSettled = notifyManager.batchCalls(
53
- defaultedOptions.onSettled,
54
- )
55
- }
61
+ >(client, get(defaultedOptionsStore))
56
62
 
57
- readable(observer).subscribe(($observer) => {
58
- observer = $observer
63
+ defaultedOptionsStore.subscribe(($defaultedOptions) => {
59
64
  // Do not notify on updates because of changes in the options because
60
65
  // these changes should already be reflected in the optimistic result.
61
- observer.setOptions(defaultedOptions, { listeners: false })
66
+ observer.setOptions($defaultedOptions, { listeners: false })
62
67
  })
63
68
 
64
69
  const result = readable(observer.getCurrentResult(), (set) => {
@@ -66,8 +71,8 @@ export function createBaseQuery<
66
71
  })
67
72
 
68
73
  const { subscribe } = derived(result, ($result) => {
69
- $result = observer.getOptimisticResult(defaultedOptions)
70
- return !defaultedOptions.notifyOnChangeProps
74
+ $result = observer.getOptimisticResult(get(defaultedOptionsStore))
75
+ return !get(defaultedOptionsStore).notifyOnChangeProps
71
76
  ? observer.trackResult($result)
72
77
  : $result
73
78
  })
@@ -1,103 +1,41 @@
1
- import {
2
- InfiniteQueryObserver,
3
- parseQueryArgs,
4
- type QueryObserver,
5
- type QueryFunction,
6
- type QueryKey,
1
+ import type {
2
+ QueryObserver,
3
+ QueryKey,
4
+ QueryClient,
5
+ RegisteredError,
6
+ InfiniteData,
7
7
  } from '@tanstack/query-core'
8
+ import { InfiniteQueryObserver } from '@tanstack/query-core'
8
9
  import type {
9
10
  CreateInfiniteQueryOptions,
10
11
  CreateInfiniteQueryResult,
12
+ WritableOrVal,
11
13
  } from './types'
12
14
  import { createBaseQuery } from './createBaseQuery'
13
15
 
14
16
  export function createInfiniteQuery<
15
- TQueryFnData = unknown,
16
- TError = unknown,
17
- TData = TQueryFnData,
18
- TQueryKey extends QueryKey = QueryKey,
19
- >(
20
- options: CreateInfiniteQueryOptions<
21
- TQueryFnData,
22
- TError,
23
- TData,
24
- TQueryFnData,
25
- TQueryKey
26
- >,
27
- ): CreateInfiniteQueryResult<TData, TError>
28
- export function createInfiniteQuery<
29
- TQueryFnData = unknown,
30
- TError = unknown,
31
- TData = TQueryFnData,
32
- TQueryKey extends QueryKey = QueryKey,
33
- >(
34
- queryKey: TQueryKey,
35
- options?: Omit<
36
- CreateInfiniteQueryOptions<
37
- TQueryFnData,
38
- TError,
39
- TData,
40
- TQueryFnData,
41
- TQueryKey
42
- >,
43
- 'queryKey'
44
- >,
45
- ): CreateInfiniteQueryResult<TData, TError>
46
- export function createInfiniteQuery<
47
- TQueryFnData = unknown,
48
- TError = unknown,
49
- TData = TQueryFnData,
17
+ TQueryFnData,
18
+ TError = RegisteredError,
19
+ TData = InfiniteData<TQueryFnData>,
50
20
  TQueryKey extends QueryKey = QueryKey,
21
+ TPageParam = unknown,
51
22
  >(
52
- queryKey: TQueryKey,
53
- queryFn: QueryFunction<TQueryFnData, TQueryKey>,
54
- options?: Omit<
23
+ options: WritableOrVal<
55
24
  CreateInfiniteQueryOptions<
56
25
  TQueryFnData,
57
26
  TError,
58
27
  TData,
59
28
  TQueryFnData,
60
- TQueryKey
61
- >,
62
- 'queryKey' | 'queryFn'
63
- >,
64
- ): CreateInfiniteQueryResult<TData, TError>
65
-
66
- export function createInfiniteQuery<
67
- TQueryFnData,
68
- TError,
69
- TData = TQueryFnData,
70
- TQueryKey extends QueryKey = QueryKey,
71
- >(
72
- arg1:
73
- | TQueryKey
74
- | CreateInfiniteQueryOptions<
75
- TQueryFnData,
76
- TError,
77
- TData,
78
- TQueryFnData,
79
- TQueryKey
80
- >,
81
- arg2?:
82
- | QueryFunction<TQueryFnData, TQueryKey>
83
- | CreateInfiniteQueryOptions<
84
- TQueryFnData,
85
- TError,
86
- TData,
87
- TQueryFnData,
88
- TQueryKey
89
- >,
90
- arg3?: CreateInfiniteQueryOptions<
91
- TQueryFnData,
92
- TError,
93
- TData,
94
- TQueryFnData,
95
- TQueryKey
29
+ TQueryKey,
30
+ TPageParam
31
+ >
96
32
  >,
33
+ queryClient?: QueryClient,
97
34
  ): CreateInfiniteQueryResult<TData, TError> {
98
- const options = parseQueryArgs(arg1, arg2, arg3)
99
35
  return createBaseQuery(
100
36
  options,
37
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
101
38
  InfiniteQueryObserver as typeof QueryObserver,
39
+ queryClient,
102
40
  ) as CreateInfiniteQueryResult<TData, TError>
103
41
  }
@@ -1,96 +1,41 @@
1
- import { readable, derived } from 'svelte/store'
2
- import {
3
- type MutationFunction,
4
- type MutationKey,
5
- MutationObserver,
6
- notifyManager,
7
- parseMutationArgs,
8
- } from '@tanstack/query-core'
1
+ import { readable, derived, writable, get } from 'svelte/store'
2
+ import type { QueryClient, RegisteredError } from '@tanstack/query-core'
3
+ import { MutationObserver, notifyManager } from '@tanstack/query-core'
9
4
  import type {
10
5
  CreateMutateFunction,
11
6
  CreateMutationOptions,
12
7
  CreateMutationResult,
8
+ WritableOrVal,
13
9
  } from './types'
14
10
  import { useQueryClient } from './useQueryClient'
11
+ import { isWritable } from './utils'
15
12
 
16
13
  export function createMutation<
17
14
  TData = unknown,
18
- TError = unknown,
15
+ TError = RegisteredError,
19
16
  TVariables = void,
20
17
  TContext = unknown,
21
18
  >(
22
- options: CreateMutationOptions<TData, TError, TVariables, TContext>,
23
- ): CreateMutationResult<TData, TError, TVariables, TContext>
24
-
25
- export function createMutation<
26
- TData = unknown,
27
- TError = unknown,
28
- TVariables = void,
29
- TContext = unknown,
30
- >(
31
- mutationFn: MutationFunction<TData, TVariables>,
32
- options?: Omit<
33
- CreateMutationOptions<TData, TError, TVariables, TContext>,
34
- 'mutationFn'
35
- >,
36
- ): CreateMutationResult<TData, TError, TVariables, TContext>
37
-
38
- export function createMutation<
39
- TData = unknown,
40
- TError = unknown,
41
- TVariables = void,
42
- TContext = unknown,
43
- >(
44
- mutationKey: MutationKey,
45
- options?: Omit<
46
- CreateMutationOptions<TData, TError, TVariables, TContext>,
47
- 'mutationKey'
19
+ options: WritableOrVal<
20
+ CreateMutationOptions<TData, TError, TVariables, TContext>
48
21
  >,
49
- ): CreateMutationResult<TData, TError, TVariables, TContext>
22
+ queryClient?: QueryClient,
23
+ ): CreateMutationResult<TData, TError, TVariables, TContext> {
24
+ const client = useQueryClient(queryClient)
50
25
 
51
- export function createMutation<
52
- TData = unknown,
53
- TError = unknown,
54
- TVariables = void,
55
- TContext = unknown,
56
- >(
57
- mutationKey: MutationKey,
58
- mutationFn?: MutationFunction<TData, TVariables>,
59
- options?: Omit<
60
- CreateMutationOptions<TData, TError, TVariables, TContext>,
61
- 'mutationKey' | 'mutationFn'
62
- >,
63
- ): CreateMutationResult<TData, TError, TVariables, TContext>
26
+ const optionsStore = isWritable(options) ? options : writable(options)
64
27
 
65
- export function createMutation<
66
- TData = unknown,
67
- TError = unknown,
68
- TVariables = void,
69
- TContext = unknown,
70
- >(
71
- arg1:
72
- | MutationKey
73
- | MutationFunction<TData, TVariables>
74
- | CreateMutationOptions<TData, TError, TVariables, TContext>,
75
- arg2?:
76
- | MutationFunction<TData, TVariables>
77
- | CreateMutationOptions<TData, TError, TVariables, TContext>,
78
- arg3?: CreateMutationOptions<TData, TError, TVariables, TContext>,
79
- ): CreateMutationResult<TData, TError, TVariables, TContext> {
80
- const options = parseMutationArgs(arg1, arg2, arg3)
81
- const queryClient = useQueryClient()
82
- let observer = new MutationObserver<TData, TError, TVariables, TContext>(
83
- queryClient,
84
- options,
28
+ const observer = new MutationObserver<TData, TError, TVariables, TContext>(
29
+ client,
30
+ get(optionsStore),
85
31
  )
86
32
  let mutate: CreateMutateFunction<TData, TError, TVariables, TContext>
87
33
 
88
- readable(observer).subscribe(($observer) => {
89
- observer = $observer
34
+ optionsStore.subscribe(($options) => {
90
35
  mutate = (variables, mutateOptions) => {
91
36
  observer.mutate(variables, mutateOptions).catch(noop)
92
37
  }
93
- observer.setOptions(options)
38
+ observer.setOptions($options)
94
39
  })
95
40
 
96
41
  const result = readable(observer.getCurrentResult(), (set) => {
@@ -2,23 +2,31 @@ import type {
2
2
  QueryKey,
3
3
  QueryFunction,
4
4
  QueryClient,
5
+ QueriesPlaceholderDataFunction,
5
6
  QueryObserverResult,
7
+ RegisteredError,
6
8
  } from '@tanstack/query-core'
7
9
 
8
10
  import { notifyManager, QueriesObserver } from '@tanstack/query-core'
9
- import { readable, type Readable } from 'svelte/store'
11
+ import { derived, get, readable, writable, type Readable } from 'svelte/store'
10
12
 
11
- import type { CreateQueryOptions } from './types'
13
+ import type { CreateQueryOptions, WritableOrVal } from './types'
12
14
  import { useQueryClient } from './useQueryClient'
15
+ import { isWritable } from './utils'
13
16
 
14
17
  // This defines the `CreateQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.
15
- // - `context` is omitted as it is passed as a root-level option to `createQueries` instead.
18
+ // `placeholderData` function does not have a parameter
16
19
  type CreateQueryOptionsForCreateQueries<
17
20
  TQueryFnData = unknown,
18
- TError = unknown,
21
+ TError = RegisteredError,
19
22
  TData = TQueryFnData,
20
23
  TQueryKey extends QueryKey = QueryKey,
21
- > = Omit<CreateQueryOptions<TQueryFnData, TError, TData, TQueryKey>, 'context'>
24
+ > = Omit<
25
+ CreateQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
26
+ 'placeholderData'
27
+ > & {
28
+ placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>
29
+ }
22
30
 
23
31
  // Avoid TS depth-limit error in case of large array literal
24
32
  type MAXIMUM_DEPTH = 20
@@ -47,16 +55,11 @@ type GetOptions<T> =
47
55
  queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>
48
56
  select: (data: any) => infer TData
49
57
  }
50
- ? CreateQueryOptionsForCreateQueries<
51
- TQueryFnData,
52
- unknown,
53
- TData,
54
- TQueryKey
55
- >
58
+ ? CreateQueryOptionsForCreateQueries<TQueryFnData, Error, TData, TQueryKey>
56
59
  : T extends { queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey> }
57
60
  ? CreateQueryOptionsForCreateQueries<
58
61
  TQueryFnData,
59
- unknown,
62
+ Error,
60
63
  TQueryFnData,
61
64
  TQueryKey
62
65
  >
@@ -140,40 +143,46 @@ export type QueriesResults<
140
143
  any
141
144
  >[]
142
145
  ? // Dynamic-size (homogenous) CreateQueryOptions array: map directly to array of results
143
- QueryObserverResult<unknown extends TData ? TQueryFnData : TData, TError>[]
146
+ QueryObserverResult<
147
+ unknown extends TData ? TQueryFnData : TData,
148
+ unknown extends TError ? RegisteredError : TError
149
+ >[]
144
150
  : // Fallback
145
151
  QueryObserverResult[]
146
152
 
147
153
  export type CreateQueriesResult<T extends any[]> = Readable<QueriesResults<T>>
148
154
 
149
- export function createQueries<T extends any[]>(
150
- queries: readonly [...QueriesOptions<T>],
151
- ): CreateQueriesResult<T> {
152
- const client: QueryClient = useQueryClient()
155
+ export function createQueries<T extends any[]>({
156
+ queries,
157
+ queryClient,
158
+ }: {
159
+ queries: WritableOrVal<[...QueriesOptions<T>]>
160
+ queryClient?: QueryClient
161
+ }): CreateQueriesResult<T> {
162
+ const client = useQueryClient(queryClient)
153
163
  // const isRestoring = useIsRestoring()
154
164
 
155
- function getDefaultQuery(newQueries: readonly [...QueriesOptions<T>]) {
156
- return newQueries.map((options) => {
165
+ const queriesStore = isWritable(queries) ? queries : writable(queries)
166
+
167
+ const defaultedQueriesStore = derived(queriesStore, ($queries) => {
168
+ return $queries.map((options) => {
157
169
  const defaultedOptions = client.defaultQueryOptions(options)
158
170
  // Make sure the results are already in fetching state before subscribing or updating options
159
171
  defaultedOptions._optimisticResults = 'optimistic'
160
172
 
161
173
  return defaultedOptions
162
174
  })
163
- }
164
-
165
- const defaultedQueries = getDefaultQuery(queries)
166
- let observer = new QueriesObserver(client, defaultedQueries)
175
+ })
176
+ const observer = new QueriesObserver(client, get(defaultedQueriesStore))
167
177
 
168
- readable(observer).subscribe(($observer) => {
169
- observer = $observer
178
+ defaultedQueriesStore.subscribe(($defaultedQueries) => {
170
179
  // Do not notify on updates because of changes in the options because
171
180
  // these changes should already be reflected in the optimistic result.
172
- observer.setQueries(defaultedQueries, { listeners: false })
181
+ observer.setQueries($defaultedQueries, { listeners: false })
173
182
  })
174
183
 
175
184
  const { subscribe } = readable(
176
- observer.getOptimisticResult(defaultedQueries) as any,
185
+ observer.getOptimisticResult(get(defaultedQueriesStore)) as any,
177
186
  (set) => {
178
187
  return observer.subscribe(notifyManager.batchCalls(set))
179
188
  },