|
1 | 1 | import { WatchedQuery } from '@powersync/common'; |
2 | | -import { reactive, UnwrapNestedRefs, watchEffect } from 'vue'; |
| 2 | +import { Ref, ref, watchEffect } from 'vue'; |
| 3 | + |
| 4 | +type RefState<ResultType = unknown, Query extends WatchedQuery<ResultType> = WatchedQuery<ResultType>> = { |
| 5 | + [K in keyof Query['state']]: Ref<Query['state'][K]>; |
| 6 | +}; |
3 | 7 |
|
4 | 8 | /** |
5 | 9 | * A composable to access and subscribe to the results of an existing {@link WatchedQuery} instance. |
@@ -27,18 +31,30 @@ export const useWatchedQuerySubscription = < |
27 | 31 | Query extends WatchedQuery<ResultType> = WatchedQuery<ResultType> |
28 | 32 | >( |
29 | 33 | query: Query |
30 | | -): UnwrapNestedRefs<Query['state']> => { |
31 | | - // Creates a reactive variable which will proxy the state |
32 | | - const state = reactive({ ...query.state }) as UnwrapNestedRefs<Query['state']>; |
| 34 | +): RefState<ResultType, Query> => { |
| 35 | + // This uses individual refs in order for the destructured use of this hook's return value to |
| 36 | + // function correctly. |
| 37 | + const data = ref(query.state.data) as Ref<Query['state']['data']>; |
| 38 | + const error = ref(query.state.error); |
| 39 | + const isLoading = ref(query.state.isLoading); |
| 40 | + const isFetching = ref(query.state.isFetching); |
33 | 41 |
|
34 | 42 | watchEffect((onCleanup) => { |
35 | 43 | const dispose = query.registerListener({ |
36 | 44 | onStateChange: (updatedState) => { |
37 | | - Object.assign(state, updatedState); |
| 45 | + data.value = updatedState.data; |
| 46 | + error.value = updatedState.error; |
| 47 | + isFetching.value = updatedState.isFetching; |
| 48 | + isLoading.value = updatedState.isLoading; |
38 | 49 | } |
39 | 50 | }); |
40 | 51 | onCleanup(() => dispose()); |
41 | 52 | }); |
42 | 53 |
|
43 | | - return state; |
| 54 | + return { |
| 55 | + data, |
| 56 | + error, |
| 57 | + isFetching, |
| 58 | + isLoading |
| 59 | + } as RefState<ResultType, Query>; |
44 | 60 | }; |
0 commit comments