@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
@@ -0,0 +1,121 @@
1
+ import type { QueryObserver } from '@tanstack/query-core'
2
+ import type { QueryKey, QueryObserverResult } from '@tanstack/query-core'
3
+ import type { CreateBaseQueryOptions } from './types'
4
+ import { useQueryClient } from './QueryClientProvider'
5
+ import {
6
+ onMount,
7
+ onCleanup,
8
+ createComputed,
9
+ createResource,
10
+ on,
11
+ batch,
12
+ } from 'solid-js'
13
+ import { createStore, unwrap } from 'solid-js/store'
14
+ import { shouldThrowError } from './utils'
15
+
16
+ // Base Query Function that is used to create the query.
17
+ export function createBaseQuery<
18
+ TQueryFnData,
19
+ TError,
20
+ TData,
21
+ TQueryData,
22
+ TQueryKey extends QueryKey,
23
+ >(
24
+ options: CreateBaseQueryOptions<
25
+ TQueryFnData,
26
+ TError,
27
+ TData,
28
+ TQueryData,
29
+ TQueryKey
30
+ >,
31
+ Observer: typeof QueryObserver,
32
+ ): QueryObserverResult<TData, TError> {
33
+ const queryClient = useQueryClient({ context: options.context })
34
+
35
+ const defaultedOptions = queryClient.defaultQueryOptions(options)
36
+ defaultedOptions._optimisticResults = 'optimistic'
37
+ const observer = new Observer(queryClient, defaultedOptions)
38
+
39
+ const [state, setState] = createStore<QueryObserverResult<TData, TError>>(
40
+ // @ts-ignore
41
+ observer.getOptimisticResult(defaultedOptions),
42
+ )
43
+
44
+ const [dataResource, { refetch, mutate }] = createResource<TData | undefined>(
45
+ () => {
46
+ return new Promise((resolve) => {
47
+ if (!(state.isFetching && state.isLoading)) {
48
+ resolve(unwrap(state.data))
49
+ }
50
+ })
51
+ },
52
+ )
53
+
54
+ batch(() => {
55
+ mutate(() => unwrap(state.data))
56
+ refetch()
57
+ })
58
+
59
+ let taskQueue: Array<() => void> = []
60
+
61
+ const unsubscribe = observer.subscribe((result) => {
62
+ taskQueue.push(() => {
63
+ batch(() => {
64
+ setState(unwrap(result))
65
+ mutate(() => unwrap(result.data))
66
+ refetch()
67
+ })
68
+ })
69
+
70
+ queueMicrotask(() => {
71
+ const taskToRun = taskQueue.pop()
72
+ if (taskToRun) {
73
+ taskToRun()
74
+ }
75
+ taskQueue = []
76
+ })
77
+ })
78
+
79
+ onCleanup(() => unsubscribe())
80
+
81
+ onMount(() => {
82
+ observer.setOptions(defaultedOptions, { listeners: false })
83
+ })
84
+
85
+ createComputed(() => {
86
+ const newDefaultedOptions = queryClient.defaultQueryOptions(options)
87
+ observer.setOptions(newDefaultedOptions)
88
+ })
89
+
90
+ createComputed(
91
+ on(
92
+ () => state.status,
93
+ () => {
94
+ if (
95
+ state.isError &&
96
+ !state.isFetching &&
97
+ shouldThrowError(observer.options.useErrorBoundary, [
98
+ state.error,
99
+ observer.getCurrentQuery(),
100
+ ])
101
+ ) {
102
+ throw state.error
103
+ }
104
+ },
105
+ ),
106
+ )
107
+
108
+ const handler = {
109
+ get(
110
+ target: QueryObserverResult<TData, TError>,
111
+ prop: keyof QueryObserverResult<TData, TError>,
112
+ ): any {
113
+ if (prop === 'data' && target.isLoading && target.isFetching) {
114
+ return dataResource()
115
+ }
116
+ return Reflect.get(target, prop)
117
+ },
118
+ }
119
+
120
+ return new Proxy(state, handler) as QueryObserverResult<TData, TError>
121
+ }
@@ -0,0 +1,116 @@
1
+ import type {
2
+ QueryObserver,
3
+ QueryFunction,
4
+ QueryOptions,
5
+ } from '@tanstack/query-core'
6
+ import { InfiniteQueryObserver } from '@tanstack/query-core'
7
+ import type {
8
+ CreateInfiniteQueryOptions,
9
+ CreateInfiniteQueryResult,
10
+ SolidQueryKey,
11
+ } from './types'
12
+ import { createBaseQuery } from './createBaseQuery'
13
+ import { createComputed } from 'solid-js'
14
+ import { createStore } from 'solid-js/store'
15
+ import { parseQueryArgs } from './utils'
16
+
17
+ export function createInfiniteQuery<
18
+ TQueryFnData = unknown,
19
+ TError = unknown,
20
+ TData = TQueryFnData,
21
+ TQueryKey extends SolidQueryKey = SolidQueryKey,
22
+ >(
23
+ options: CreateInfiniteQueryOptions<
24
+ TQueryFnData,
25
+ TError,
26
+ TData,
27
+ TQueryFnData,
28
+ TQueryKey
29
+ >,
30
+ ): CreateInfiniteQueryResult<TData, TError>
31
+ export function createInfiniteQuery<
32
+ TQueryFnData = unknown,
33
+ TError = unknown,
34
+ TData = TQueryFnData,
35
+ TQueryKey extends SolidQueryKey = SolidQueryKey,
36
+ >(
37
+ queryKey: TQueryKey,
38
+ options?: Omit<
39
+ CreateInfiniteQueryOptions<
40
+ TQueryFnData,
41
+ TError,
42
+ TData,
43
+ TQueryFnData,
44
+ TQueryKey
45
+ >,
46
+ 'queryKey'
47
+ >,
48
+ ): CreateInfiniteQueryResult<TData, TError>
49
+ export function createInfiniteQuery<
50
+ TQueryFnData = unknown,
51
+ TError = unknown,
52
+ TData = TQueryFnData,
53
+ TQueryKey extends SolidQueryKey = SolidQueryKey,
54
+ >(
55
+ queryKey: TQueryKey,
56
+ queryFn: QueryFunction<TQueryFnData, ReturnType<TQueryKey>>,
57
+ options?: Omit<
58
+ CreateInfiniteQueryOptions<
59
+ TQueryFnData,
60
+ TError,
61
+ TData,
62
+ TQueryFnData,
63
+ TQueryKey
64
+ >,
65
+ 'queryKey' | 'queryFn'
66
+ >,
67
+ ): CreateInfiniteQueryResult<TData, TError>
68
+ export function createInfiniteQuery<
69
+ TQueryFnData,
70
+ TError,
71
+ TData = TQueryFnData,
72
+ TQueryKey extends SolidQueryKey = SolidQueryKey,
73
+ >(
74
+ arg1:
75
+ | TQueryKey
76
+ | CreateInfiniteQueryOptions<
77
+ TQueryFnData,
78
+ TError,
79
+ TData,
80
+ TQueryFnData,
81
+ TQueryKey
82
+ >,
83
+ arg2?:
84
+ | QueryFunction<TQueryFnData, ReturnType<TQueryKey>>
85
+ | CreateInfiniteQueryOptions<
86
+ TQueryFnData,
87
+ TError,
88
+ TData,
89
+ TQueryFnData,
90
+ TQueryKey
91
+ >,
92
+ arg3?: CreateInfiniteQueryOptions<
93
+ TQueryFnData,
94
+ TError,
95
+ TData,
96
+ TQueryFnData,
97
+ TQueryKey
98
+ >,
99
+ ): CreateInfiniteQueryResult<TData, TError> {
100
+ // The parseQuery Args functions helps normalize the arguments into the correct form.
101
+ // Whatever the parameters are, they are normalized into the correct form.
102
+ const [parsedOptions, setParsedOptions] = createStore(
103
+ parseQueryArgs(arg1, arg2, arg3),
104
+ )
105
+
106
+ // Watch for changes in the options and update the parsed options.
107
+ createComputed(() => {
108
+ const newParsedOptions = parseQueryArgs(arg1, arg2, arg3)
109
+ setParsedOptions(newParsedOptions)
110
+ })
111
+
112
+ return createBaseQuery(
113
+ parsedOptions as QueryOptions<any, any, any, ReturnType<TQueryKey>>,
114
+ InfiniteQueryObserver as typeof QueryObserver,
115
+ ) as CreateInfiniteQueryResult<TData, TError>
116
+ }
@@ -0,0 +1,131 @@
1
+ import type { MutationFunction, MutationKey } from '@tanstack/query-core'
2
+ import { parseMutationArgs, MutationObserver } from '@tanstack/query-core'
3
+ import { useQueryClient } from './QueryClientProvider'
4
+ import type {
5
+ CreateMutateFunction,
6
+ CreateMutationOptions,
7
+ CreateMutationResult,
8
+ } from './types'
9
+ import { createComputed, onCleanup, on } from 'solid-js'
10
+ import { createStore } from 'solid-js/store'
11
+ import { shouldThrowError } from './utils'
12
+
13
+ // HOOK
14
+ export function createMutation<
15
+ TData = unknown,
16
+ TError = unknown,
17
+ TVariables = void,
18
+ TContext = unknown,
19
+ >(
20
+ options: CreateMutationOptions<TData, TError, TVariables, TContext>,
21
+ ): CreateMutationResult<TData, TError, TVariables, TContext>
22
+ export function createMutation<
23
+ TData = unknown,
24
+ TError = unknown,
25
+ TVariables = void,
26
+ TContext = unknown,
27
+ >(
28
+ mutationFn: MutationFunction<TData, TVariables>,
29
+ options?: Omit<
30
+ CreateMutationOptions<TData, TError, TVariables, TContext>,
31
+ 'mutationFn'
32
+ >,
33
+ ): CreateMutationResult<TData, TError, TVariables, TContext>
34
+ export function createMutation<
35
+ TData = unknown,
36
+ TError = unknown,
37
+ TVariables = void,
38
+ TContext = unknown,
39
+ >(
40
+ mutationKey: MutationKey,
41
+ options?: Omit<
42
+ CreateMutationOptions<TData, TError, TVariables, TContext>,
43
+ 'mutationKey'
44
+ >,
45
+ ): CreateMutationResult<TData, TError, TVariables, TContext>
46
+ export function createMutation<
47
+ TData = unknown,
48
+ TError = unknown,
49
+ TVariables = void,
50
+ TContext = unknown,
51
+ >(
52
+ mutationKey: MutationKey,
53
+ mutationFn?: MutationFunction<TData, TVariables>,
54
+ options?: Omit<
55
+ CreateMutationOptions<TData, TError, TVariables, TContext>,
56
+ 'mutationKey' | 'mutationFn'
57
+ >,
58
+ ): CreateMutationResult<TData, TError, TVariables, TContext>
59
+ export function createMutation<
60
+ TData = unknown,
61
+ TError = unknown,
62
+ TVariables = void,
63
+ TContext = unknown,
64
+ >(
65
+ arg1:
66
+ | MutationKey
67
+ | MutationFunction<TData, TVariables>
68
+ | CreateMutationOptions<TData, TError, TVariables, TContext>,
69
+ arg2?:
70
+ | MutationFunction<TData, TVariables>
71
+ | CreateMutationOptions<TData, TError, TVariables, TContext>,
72
+ arg3?: CreateMutationOptions<TData, TError, TVariables, TContext>,
73
+ ): CreateMutationResult<TData, TError, TVariables, TContext> {
74
+ const [options, setOptions] = createStore(parseMutationArgs(arg1, arg2, arg3))
75
+ const queryClient = useQueryClient({ context: options.context })
76
+
77
+ const observer = new MutationObserver<TData, TError, TVariables, TContext>(
78
+ queryClient,
79
+ options,
80
+ )
81
+
82
+ const mutate: CreateMutateFunction<TData, TError, TVariables, TContext> = (
83
+ variables,
84
+ mutateOptions,
85
+ ) => {
86
+ observer.mutate(variables, mutateOptions).catch(noop)
87
+ }
88
+
89
+ const [state, setState] = createStore<
90
+ CreateMutationResult<TData, TError, TVariables, TContext>
91
+ >({
92
+ ...observer.getCurrentResult(),
93
+ mutate,
94
+ mutateAsync: observer.getCurrentResult().mutate,
95
+ })
96
+
97
+ createComputed(() => {
98
+ const newParsedOptions = parseMutationArgs(arg1, arg2, arg3)
99
+ setOptions(newParsedOptions)
100
+ observer.setOptions(newParsedOptions)
101
+ })
102
+
103
+ createComputed(
104
+ on(
105
+ () => state.status,
106
+ () => {
107
+ if (
108
+ state.isError &&
109
+ shouldThrowError(observer.options.useErrorBoundary, [state.error])
110
+ ) {
111
+ throw state.error
112
+ }
113
+ },
114
+ ),
115
+ )
116
+
117
+ const unsubscribe = observer.subscribe((result) => {
118
+ setState({
119
+ ...result,
120
+ mutate,
121
+ mutateAsync: result.mutate,
122
+ })
123
+ })
124
+
125
+ onCleanup(unsubscribe)
126
+
127
+ return state
128
+ }
129
+
130
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
131
+ function noop() {}
@@ -0,0 +1,203 @@
1
+ import { createComputed, onCleanup, onMount } from 'solid-js'
2
+ import type { QueryFunction } from '@tanstack/query-core'
3
+ import { QueriesObserver } from '@tanstack/query-core'
4
+ import { useQueryClient } from './QueryClientProvider'
5
+ import type {
6
+ CreateQueryOptions,
7
+ CreateQueryResult,
8
+ SolidQueryKey,
9
+ } from './types'
10
+ import { createStore, unwrap } from 'solid-js/store'
11
+ import { scheduleMicrotask } from './utils'
12
+
13
+ // This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.
14
+ // - `context` is omitted as it is passed as a root-level option to `useQueries` instead.
15
+ type CreateQueryOptionsForCreateQueries<
16
+ TQueryFnData = unknown,
17
+ TError = unknown,
18
+ TData = TQueryFnData,
19
+ TQueryKey extends SolidQueryKey = SolidQueryKey,
20
+ > = Omit<CreateQueryOptions<TQueryFnData, TError, TData, TQueryKey>, 'context'>
21
+
22
+ // Avoid TS depth-limit error in case of large array literal
23
+ type MAXIMUM_DEPTH = 20
24
+
25
+ type GetOptions<T> =
26
+ // Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData }
27
+ T extends {
28
+ queryFnData: infer TQueryFnData
29
+ error?: infer TError
30
+ data: infer TData
31
+ }
32
+ ? CreateQueryOptionsForCreateQueries<TQueryFnData, TError, TData>
33
+ : T extends { queryFnData: infer TQueryFnData; error?: infer TError }
34
+ ? CreateQueryOptionsForCreateQueries<TQueryFnData, TError>
35
+ : T extends { data: infer TData; error?: infer TError }
36
+ ? CreateQueryOptionsForCreateQueries<unknown, TError, TData>
37
+ : // Part 2: responsible for applying explicit type parameter to function arguments, if tuple [TQueryFnData, TError, TData]
38
+ T extends [infer TQueryFnData, infer TError, infer TData]
39
+ ? CreateQueryOptionsForCreateQueries<TQueryFnData, TError, TData>
40
+ : T extends [infer TQueryFnData, infer TError]
41
+ ? CreateQueryOptionsForCreateQueries<TQueryFnData, TError>
42
+ : T extends [infer TQueryFnData]
43
+ ? CreateQueryOptionsForCreateQueries<TQueryFnData>
44
+ : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided
45
+ T extends {
46
+ queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>
47
+ select: (data: any) => infer TData
48
+ }
49
+ ? CreateQueryOptionsForCreateQueries<
50
+ TQueryFnData,
51
+ unknown,
52
+ TData,
53
+ () => TQueryKey
54
+ >
55
+ : T extends { queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey> }
56
+ ? CreateQueryOptionsForCreateQueries<
57
+ TQueryFnData,
58
+ unknown,
59
+ TQueryFnData,
60
+ () => TQueryKey
61
+ >
62
+ : // Fallback
63
+ CreateQueryOptionsForCreateQueries
64
+
65
+ type GetResults<T> =
66
+ // Part 1: responsible for mapping explicit type parameter to function result, if object
67
+ T extends { queryFnData: any; error?: infer TError; data: infer TData }
68
+ ? CreateQueryResult<TData, TError>
69
+ : T extends { queryFnData: infer TQueryFnData; error?: infer TError }
70
+ ? CreateQueryResult<TQueryFnData, TError>
71
+ : T extends { data: infer TData; error?: infer TError }
72
+ ? CreateQueryResult<TData, TError>
73
+ : // Part 2: responsible for mapping explicit type parameter to function result, if tuple
74
+ T extends [any, infer TError, infer TData]
75
+ ? CreateQueryResult<TData, TError>
76
+ : T extends [infer TQueryFnData, infer TError]
77
+ ? CreateQueryResult<TQueryFnData, TError>
78
+ : T extends [infer TQueryFnData]
79
+ ? CreateQueryResult<TQueryFnData>
80
+ : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided
81
+ T extends {
82
+ queryFn?: QueryFunction<unknown, any>
83
+ select: (data: any) => infer TData
84
+ }
85
+ ? CreateQueryResult<TData>
86
+ : T extends { queryFn?: QueryFunction<infer TQueryFnData, any> }
87
+ ? CreateQueryResult<TQueryFnData>
88
+ : // Fallback
89
+ CreateQueryResult
90
+
91
+ /**
92
+ * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
93
+ */
94
+ export type QueriesOptions<
95
+ T extends any[],
96
+ Result extends any[] = [],
97
+ Depth extends ReadonlyArray<number> = [],
98
+ > = Depth['length'] extends MAXIMUM_DEPTH
99
+ ? CreateQueryOptionsForCreateQueries[]
100
+ : T extends []
101
+ ? []
102
+ : T extends [infer Head]
103
+ ? [...Result, GetOptions<Head>]
104
+ : T extends [infer Head, ...infer Tail]
105
+ ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>
106
+ : unknown[] extends T
107
+ ? T
108
+ : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type!
109
+ // use this to infer the param types in the case of Array.map() argument
110
+ T extends CreateQueryOptionsForCreateQueries<
111
+ infer TQueryFnData,
112
+ infer TError,
113
+ infer TData,
114
+ infer TQueryKey
115
+ >[]
116
+ ? CreateQueryOptionsForCreateQueries<TQueryFnData, TError, TData, TQueryKey>[]
117
+ : // Fallback
118
+ CreateQueryOptionsForCreateQueries[]
119
+
120
+ /**
121
+ * QueriesResults reducer recursively maps type param to results
122
+ */
123
+ export type QueriesResults<
124
+ T extends any[],
125
+ Result extends any[] = [],
126
+ Depth extends ReadonlyArray<number> = [],
127
+ > = Depth['length'] extends MAXIMUM_DEPTH
128
+ ? CreateQueryResult[]
129
+ : T extends []
130
+ ? []
131
+ : T extends [infer Head]
132
+ ? [...Result, GetResults<Head>]
133
+ : T extends [infer Head, ...infer Tail]
134
+ ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>
135
+ : T extends CreateQueryOptionsForCreateQueries<
136
+ infer TQueryFnData,
137
+ infer TError,
138
+ infer TData,
139
+ any
140
+ >[]
141
+ ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results
142
+ CreateQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[]
143
+ : // Fallback
144
+ CreateQueryResult[]
145
+
146
+ type ArrType<T> = T extends (infer U)[] ? U : never
147
+
148
+ export function createQueries<T extends any[]>(queriesOptions: {
149
+ queries: readonly [...QueriesOptions<T>]
150
+ context?: CreateQueryOptions['context']
151
+ }): QueriesResults<T> {
152
+ const queryClient = useQueryClient({ context: queriesOptions.context })
153
+
154
+ const normalizeOptions = (
155
+ options: ArrType<typeof queriesOptions.queries>,
156
+ ) => {
157
+ const normalizedOptions = { ...options, queryKey: options.queryKey?.() }
158
+ const defaultedOptions = queryClient.defaultQueryOptions(normalizedOptions)
159
+ defaultedOptions._optimisticResults = 'optimistic'
160
+ return defaultedOptions
161
+ }
162
+
163
+ const defaultedQueries = queriesOptions.queries.map((options) =>
164
+ normalizeOptions(options),
165
+ )
166
+
167
+ const observer = new QueriesObserver(queryClient, defaultedQueries)
168
+
169
+ const [state, setState] = createStore(
170
+ observer.getOptimisticResult(defaultedQueries),
171
+ )
172
+
173
+ const taskQueue: Array<() => void> = []
174
+
175
+ const unsubscribe = observer.subscribe((result) => {
176
+ taskQueue.push(() => {
177
+ setState(unwrap(result))
178
+ })
179
+
180
+ scheduleMicrotask(() => {
181
+ const taskToRun = taskQueue.pop()
182
+ if (taskToRun) {
183
+ taskToRun()
184
+ taskQueue.splice(0, taskQueue.length)
185
+ }
186
+ })
187
+ })
188
+
189
+ onCleanup(unsubscribe)
190
+
191
+ onMount(() => {
192
+ observer.setQueries(defaultedQueries, { listeners: false })
193
+ })
194
+
195
+ createComputed(() => {
196
+ const updateDefaultedQueries = queriesOptions.queries.map((options) =>
197
+ normalizeOptions(options),
198
+ )
199
+ observer.setQueries(updateDefaultedQueries)
200
+ })
201
+
202
+ return state as QueriesResults<T>
203
+ }