forked from powersync-ja/powersync-js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseQueries.ts
More file actions
127 lines (108 loc) · 4 KB
/
useQueries.ts
File metadata and controls
127 lines (108 loc) · 4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { type CompilableQuery } from '@powersync/common';
import { usePowerSync } from '@powersync/react';
import * as Tanstack from '@tanstack/react-query';
import { useMemo } from 'react';
import { usePowerSyncQueries } from './usePowerSyncQueries';
export type PowerSyncQueryOptions<T> = {
query?: string | CompilableQuery<T>;
parameters?: any[];
};
export type PowerSyncQueryOption<T = unknown[]> = Tanstack.UseQueryOptions<T[]> & PowerSyncQueryOptions<T>;
export type InferQueryResults<TQueries extends readonly unknown[]> = {
[K in keyof TQueries]: TQueries[K] extends { query: CompilableQuery<infer TData> }
? Tanstack.UseQueryResult<TData[]>
: Tanstack.UseQueryResult<unknown[]>;
};
export type ExplicitQueryResults<T extends readonly unknown[]> = {
[K in keyof T]: Tanstack.UseQueryResult<T[K][]>;
};
export type EnhancedInferQueryResults<TQueries extends readonly unknown[]> = {
[K in keyof TQueries]: TQueries[K] extends { query: CompilableQuery<infer TData> }
? Tanstack.UseQueryResult<TData[]> & { queryKey: Tanstack.QueryKey }
: Tanstack.UseQueryResult<unknown[]> & { queryKey: Tanstack.QueryKey };
};
export type EnhancedExplicitQueryResults<T extends readonly unknown[]> = {
[K in keyof T]: Tanstack.UseQueryResult<T[K][]> & { queryKey: Tanstack.QueryKey };
};
// Explicit generic typing with combine
export function useQueries<T extends readonly unknown[], TCombined>(
options: {
queries: readonly [...{ [K in keyof T]: PowerSyncQueryOption<T[K]> }];
combine: (results: EnhancedExplicitQueryResults<T>) => TCombined;
},
queryClient?: Tanstack.QueryClient
): TCombined;
// Explicit generic typing without combine
export function useQueries<T extends readonly unknown[]>(
options: {
queries: readonly [...{ [K in keyof T]: PowerSyncQueryOption<T[K]> }];
combine?: undefined;
},
queryClient?: Tanstack.QueryClient
): ExplicitQueryResults<T>;
// Auto inference with combine
export function useQueries<TQueries extends readonly PowerSyncQueryOption[], TCombined>(
options: {
queries: readonly [...TQueries];
combine: (results: EnhancedInferQueryResults<TQueries>) => TCombined;
},
queryClient?: Tanstack.QueryClient
): TCombined;
// Auto inference without combine
export function useQueries<TQueries extends readonly PowerSyncQueryOption[]>(
options: {
queries: readonly [...TQueries];
combine?: undefined;
},
queryClient?: Tanstack.QueryClient
): InferQueryResults<TQueries>;
// Implementation
export function useQueries(
options: {
queries: readonly (Tanstack.UseQueryOptions & PowerSyncQueryOptions<unknown>)[];
combine?: (results: (Tanstack.UseQueryResult<unknown, unknown> & { queryKey: Tanstack.QueryKey })[]) => unknown;
},
queryClient: Tanstack.QueryClient = Tanstack.useQueryClient()
) {
const powerSync = usePowerSync();
if (!powerSync) {
throw new Error('PowerSync is not available');
}
const queriesInput = options.queries;
const powerSyncQueriesInput = useMemo(
() =>
queriesInput.map((queryOptions) => ({
query: queryOptions.query,
parameters: queryOptions.parameters,
queryKey: queryOptions.queryKey
})),
[queriesInput]
);
const states = usePowerSyncQueries(powerSyncQueriesInput, queryClient);
const queries = useMemo(() => {
return queriesInput.map((queryOptions, idx) => {
const { query, parameters, ...rest } = queryOptions;
const state = states[idx];
return {
...rest,
queryFn: query ? state.queryFn : rest.queryFn,
queryKey: rest.queryKey
};
});
}, [queriesInput, states]);
return Tanstack.useQueries(
{
queries: queries as Tanstack.QueriesOptions<any>,
combine: options.combine
? (results) => {
const enhancedResultsWithQueryKey = results.map((result, index) => ({
...result,
queryKey: queries[index].queryKey
}));
return options.combine?.(enhancedResultsWithQueryKey);
}
: undefined
},
queryClient
);
}