@tanstack/solid-query 5.35.5 → 5.36.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.
package/build/dev.cjs CHANGED
@@ -380,9 +380,7 @@ function useIsMutating(filters, queryClient) {
380
380
  }
381
381
  function getResult(mutationCache, options) {
382
382
  return mutationCache.findAll(options.filters).map(
383
- (mutation) => options.select ? options.select(
384
- mutation
385
- ) : mutation.state
383
+ (mutation) => options.select ? options.select(mutation) : mutation.state
386
384
  );
387
385
  }
388
386
  function useMutationState(options = () => ({}), queryClient) {
package/build/dev.js CHANGED
@@ -379,9 +379,7 @@ function useIsMutating(filters, queryClient) {
379
379
  }
380
380
  function getResult(mutationCache, options) {
381
381
  return mutationCache.findAll(options.filters).map(
382
- (mutation) => options.select ? options.select(
383
- mutation
384
- ) : mutation.state
382
+ (mutation) => options.select ? options.select(mutation) : mutation.state
385
383
  );
386
384
  }
387
385
  function useMutationState(options = () => ({}), queryClient) {
package/build/index.cjs CHANGED
@@ -371,9 +371,7 @@ function useIsMutating(filters, queryClient) {
371
371
  }
372
372
  function getResult(mutationCache, options) {
373
373
  return mutationCache.findAll(options.filters).map(
374
- (mutation) => options.select ? options.select(
375
- mutation
376
- ) : mutation.state
374
+ (mutation) => options.select ? options.select(mutation) : mutation.state
377
375
  );
378
376
  }
379
377
  function useMutationState(options = () => ({}), queryClient) {
package/build/index.d.cts CHANGED
@@ -120,7 +120,7 @@ declare function useIsMutating(filters?: Accessor<MutationFilters>, queryClient?
120
120
 
121
121
  type MutationStateOptions<TResult = MutationState> = {
122
122
  filters?: MutationFilters;
123
- select?: (mutation: Mutation<unknown, DefaultError, unknown, unknown>) => TResult;
123
+ select?: (mutation: Mutation) => TResult;
124
124
  };
125
125
  declare function useMutationState<TResult = MutationState>(options?: Accessor<MutationStateOptions<TResult>>, queryClient?: Accessor<QueryClient>): Accessor<Array<TResult>>;
126
126
 
package/build/index.d.ts CHANGED
@@ -120,7 +120,7 @@ declare function useIsMutating(filters?: Accessor<MutationFilters>, queryClient?
120
120
 
121
121
  type MutationStateOptions<TResult = MutationState> = {
122
122
  filters?: MutationFilters;
123
- select?: (mutation: Mutation<unknown, DefaultError, unknown, unknown>) => TResult;
123
+ select?: (mutation: Mutation) => TResult;
124
124
  };
125
125
  declare function useMutationState<TResult = MutationState>(options?: Accessor<MutationStateOptions<TResult>>, queryClient?: Accessor<QueryClient>): Accessor<Array<TResult>>;
126
126
 
package/build/index.js CHANGED
@@ -370,9 +370,7 @@ function useIsMutating(filters, queryClient) {
370
370
  }
371
371
  function getResult(mutationCache, options) {
372
372
  return mutationCache.findAll(options.filters).map(
373
- (mutation) => options.select ? options.select(
374
- mutation
375
- ) : mutation.state
373
+ (mutation) => options.select ? options.select(mutation) : mutation.state
376
374
  );
377
375
  }
378
376
  function useMutationState(options = () => ({}), queryClient) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/solid-query",
3
- "version": "5.35.5",
3
+ "version": "5.36.1",
4
4
  "description": "Primitives for managing, caching and syncing asynchronous and remote data in Solid",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -45,7 +45,7 @@
45
45
  ],
46
46
  "dependencies": {
47
47
  "solid-js": "^1.8.14",
48
- "@tanstack/query-core": "5.35.5"
48
+ "@tanstack/query-core": "5.36.1"
49
49
  },
50
50
  "devDependencies": {
51
51
  "tsup-preset-solid": "^2.2.0",
@@ -103,7 +103,9 @@ describe('useInfiniteQuery', () => {
103
103
  isFetchedAfterMount: false,
104
104
  isFetching: true,
105
105
  isPaused: false,
106
+ isFetchNextPageError: false,
106
107
  isFetchingNextPage: false,
108
+ isFetchPreviousPageError: false,
107
109
  isFetchingPreviousPage: false,
108
110
  isPending: true,
109
111
  isLoading: true,
@@ -136,7 +138,9 @@ describe('useInfiniteQuery', () => {
136
138
  isFetchedAfterMount: true,
137
139
  isFetching: false,
138
140
  isPaused: false,
141
+ isFetchNextPageError: false,
139
142
  isFetchingNextPage: false,
143
+ isFetchPreviousPageError: false,
140
144
  isFetchingPreviousPage: false,
141
145
  isPending: false,
142
146
  isLoading: false,
@@ -679,6 +683,330 @@ describe('useInfiniteQuery', () => {
679
683
  })
680
684
  })
681
685
 
686
+ it('should return the correct states when refetch fails', async () => {
687
+ const key = queryKey()
688
+ const states: Array<
689
+ Partial<CreateInfiniteQueryResult<InfiniteData<number>>>
690
+ > = []
691
+ let isRefetch = false
692
+
693
+ function Page() {
694
+ const state = createInfiniteQuery(() => ({
695
+ queryKey: key,
696
+ queryFn: async ({ pageParam }) => {
697
+ await sleep(10)
698
+ if (isRefetch) {
699
+ throw new Error()
700
+ } else {
701
+ return Number(pageParam)
702
+ }
703
+ },
704
+ getPreviousPageParam: (firstPage) => firstPage - 1,
705
+ getNextPageParam: (lastPage) => lastPage + 1,
706
+ initialPageParam: 10,
707
+ notifyOnChangeProps: 'all',
708
+ retry: false,
709
+ }))
710
+
711
+ createRenderEffect(() => {
712
+ states.push({
713
+ data: state.data ? JSON.parse(JSON.stringify(state.data)) : undefined,
714
+ isFetching: state.isFetching,
715
+ isFetchNextPageError: state.isFetchNextPageError,
716
+ isFetchingNextPage: state.isFetchingNextPage,
717
+ isFetchPreviousPageError: state.isFetchPreviousPageError,
718
+ isFetchingPreviousPage: state.isFetchingPreviousPage,
719
+ isRefetchError: state.isRefetchError,
720
+ isRefetching: state.isRefetching,
721
+ })
722
+ })
723
+
724
+ return (
725
+ <div>
726
+ <button
727
+ onClick={() => {
728
+ isRefetch = true
729
+ state.refetch()
730
+ }}
731
+ >
732
+ refetch
733
+ </button>
734
+ <div>data: {state.data?.pages.join(',') ?? 'null'}</div>
735
+ <div>isFetching: {String(state.isFetching)}</div>
736
+ </div>
737
+ )
738
+ }
739
+
740
+ const rendered = render(() => (
741
+ <QueryClientProvider client={queryClient}>
742
+ <Page />
743
+ </QueryClientProvider>
744
+ ))
745
+
746
+ await waitFor(() => rendered.getByText('data: 10'))
747
+ fireEvent.click(rendered.getByRole('button', { name: /refetch/i }))
748
+
749
+ await waitFor(() => rendered.getByText('isFetching: false'))
750
+ await waitFor(() => expect(states.length).toBe(4))
751
+
752
+ // Initial fetch
753
+ expect(states[0]).toMatchObject({
754
+ data: undefined,
755
+ isFetching: true,
756
+ isFetchNextPageError: false,
757
+ isFetchingNextPage: false,
758
+ isFetchPreviousPageError: false,
759
+ isFetchingPreviousPage: false,
760
+ isRefetchError: false,
761
+ isRefetching: false,
762
+ })
763
+ // Initial fetch done
764
+ expect(states[1]).toMatchObject({
765
+ data: { pages: [10] },
766
+ isFetching: false,
767
+ isFetchNextPageError: false,
768
+ isFetchingNextPage: false,
769
+ isFetchPreviousPageError: false,
770
+ isFetchingPreviousPage: false,
771
+ isRefetchError: false,
772
+ isRefetching: false,
773
+ })
774
+ // Refetch
775
+ expect(states[2]).toMatchObject({
776
+ data: { pages: [10] },
777
+ isFetching: true,
778
+ isFetchNextPageError: false,
779
+ isFetchingNextPage: false,
780
+ isFetchPreviousPageError: false,
781
+ isFetchingPreviousPage: false,
782
+ isRefetchError: false,
783
+ isRefetching: true,
784
+ })
785
+ // Refetch failed
786
+ expect(states[3]).toMatchObject({
787
+ data: { pages: [10] },
788
+ isFetching: false,
789
+ isFetchNextPageError: false,
790
+ isFetchingNextPage: false,
791
+ isFetchPreviousPageError: false,
792
+ isFetchingPreviousPage: false,
793
+ isRefetchError: true,
794
+ isRefetching: false,
795
+ })
796
+ })
797
+
798
+ it('should return the correct states when fetchNextPage fails', async () => {
799
+ const key = queryKey()
800
+ const states: Array<
801
+ Partial<CreateInfiniteQueryResult<InfiniteData<number>>>
802
+ > = []
803
+
804
+ function Page() {
805
+ const state = createInfiniteQuery(() => ({
806
+ queryKey: key,
807
+ queryFn: async ({ pageParam }) => {
808
+ await sleep(10)
809
+ if (pageParam !== 10) {
810
+ throw new Error()
811
+ } else {
812
+ return Number(pageParam)
813
+ }
814
+ },
815
+ getPreviousPageParam: (firstPage) => firstPage - 1,
816
+ getNextPageParam: (lastPage) => lastPage + 1,
817
+ initialPageParam: 10,
818
+ notifyOnChangeProps: 'all',
819
+ retry: false,
820
+ }))
821
+
822
+ createRenderEffect(() => {
823
+ states.push({
824
+ data: state.data ? JSON.parse(JSON.stringify(state.data)) : undefined,
825
+ isFetching: state.isFetching,
826
+ isFetchNextPageError: state.isFetchNextPageError,
827
+ isFetchingNextPage: state.isFetchingNextPage,
828
+ isFetchPreviousPageError: state.isFetchPreviousPageError,
829
+ isFetchingPreviousPage: state.isFetchingPreviousPage,
830
+ isRefetchError: state.isRefetchError,
831
+ isRefetching: state.isRefetching,
832
+ })
833
+ })
834
+
835
+ return (
836
+ <div>
837
+ <button onClick={() => state.fetchNextPage()}>fetchNextPage</button>
838
+ <div>data: {state.data?.pages.join(',') ?? 'null'}</div>
839
+ <div>isFetching: {String(state.isFetching)}</div>
840
+ </div>
841
+ )
842
+ }
843
+
844
+ const rendered = render(() => (
845
+ <QueryClientProvider client={queryClient}>
846
+ <Page />
847
+ </QueryClientProvider>
848
+ ))
849
+
850
+ await waitFor(() => rendered.getByText('data: 10'))
851
+ fireEvent.click(rendered.getByRole('button', { name: /fetchNextPage/i }))
852
+
853
+ await waitFor(() => rendered.getByText('isFetching: false'))
854
+ await waitFor(() => expect(states.length).toBe(4))
855
+
856
+ // Initial fetch
857
+ expect(states[0]).toMatchObject({
858
+ data: undefined,
859
+ isFetching: true,
860
+ isFetchNextPageError: false,
861
+ isFetchingNextPage: false,
862
+ isFetchPreviousPageError: false,
863
+ isFetchingPreviousPage: false,
864
+ isRefetchError: false,
865
+ isRefetching: false,
866
+ })
867
+ // Initial fetch done
868
+ expect(states[1]).toMatchObject({
869
+ data: { pages: [10] },
870
+ isFetching: false,
871
+ isFetchNextPageError: false,
872
+ isFetchingNextPage: false,
873
+ isFetchPreviousPageError: false,
874
+ isFetchingPreviousPage: false,
875
+ isRefetchError: false,
876
+ isRefetching: false,
877
+ })
878
+ // Fetch next page
879
+ expect(states[2]).toMatchObject({
880
+ data: { pages: [10] },
881
+ isFetching: true,
882
+ isFetchNextPageError: false,
883
+ isFetchingNextPage: true,
884
+ isFetchPreviousPageError: false,
885
+ isFetchingPreviousPage: false,
886
+ isRefetchError: false,
887
+ isRefetching: false,
888
+ })
889
+ // Fetch next page failed
890
+ expect(states[3]).toMatchObject({
891
+ data: { pages: [10] },
892
+ isFetching: false,
893
+ isFetchNextPageError: true,
894
+ isFetchingNextPage: false,
895
+ isFetchPreviousPageError: false,
896
+ isFetchingPreviousPage: false,
897
+ isRefetchError: false,
898
+ isRefetching: false,
899
+ })
900
+ })
901
+
902
+ it('should return the correct states when fetchPreviousPage fails', async () => {
903
+ const key = queryKey()
904
+ const states: Array<
905
+ Partial<CreateInfiniteQueryResult<InfiniteData<number>>>
906
+ > = []
907
+
908
+ function Page() {
909
+ const state = createInfiniteQuery(() => ({
910
+ queryKey: key,
911
+ queryFn: async ({ pageParam }) => {
912
+ await sleep(10)
913
+ if (pageParam !== 10) {
914
+ throw new Error()
915
+ } else {
916
+ return Number(pageParam)
917
+ }
918
+ },
919
+ getPreviousPageParam: (firstPage) => firstPage - 1,
920
+ getNextPageParam: (lastPage) => lastPage + 1,
921
+ initialPageParam: 10,
922
+ notifyOnChangeProps: 'all',
923
+ retry: false,
924
+ }))
925
+
926
+ createRenderEffect(() => {
927
+ states.push({
928
+ data: state.data ? JSON.parse(JSON.stringify(state.data)) : undefined,
929
+ isFetching: state.isFetching,
930
+ isFetchNextPageError: state.isFetchNextPageError,
931
+ isFetchingNextPage: state.isFetchingNextPage,
932
+ isFetchPreviousPageError: state.isFetchPreviousPageError,
933
+ isFetchingPreviousPage: state.isFetchingPreviousPage,
934
+ isRefetchError: state.isRefetchError,
935
+ isRefetching: state.isRefetching,
936
+ })
937
+ })
938
+
939
+ return (
940
+ <div>
941
+ <button onClick={() => state.fetchPreviousPage()}>
942
+ fetchPreviousPage
943
+ </button>
944
+ <div>data: {state.data?.pages.join(',') ?? 'null'}</div>
945
+ <div>isFetching: {String(state.isFetching)}</div>
946
+ </div>
947
+ )
948
+ }
949
+
950
+ const rendered = render(() => (
951
+ <QueryClientProvider client={queryClient}>
952
+ <Page />
953
+ </QueryClientProvider>
954
+ ))
955
+
956
+ await waitFor(() => rendered.getByText('data: 10'))
957
+ fireEvent.click(
958
+ rendered.getByRole('button', { name: /fetchPreviousPage/i }),
959
+ )
960
+
961
+ await waitFor(() => rendered.getByText('isFetching: false'))
962
+ await waitFor(() => expect(states.length).toBe(4))
963
+
964
+ // Initial fetch
965
+ expect(states[0]).toMatchObject({
966
+ data: undefined,
967
+ isFetching: true,
968
+ isFetchNextPageError: false,
969
+ isFetchingNextPage: false,
970
+ isFetchPreviousPageError: false,
971
+ isFetchingPreviousPage: false,
972
+ isRefetchError: false,
973
+ isRefetching: false,
974
+ })
975
+ // Initial fetch done
976
+ expect(states[1]).toMatchObject({
977
+ data: { pages: [10] },
978
+ isFetching: false,
979
+ isFetchNextPageError: false,
980
+ isFetchingNextPage: false,
981
+ isFetchPreviousPageError: false,
982
+ isFetchingPreviousPage: false,
983
+ isRefetchError: false,
984
+ isRefetching: false,
985
+ })
986
+ // Fetch previous page
987
+ expect(states[2]).toMatchObject({
988
+ data: { pages: [10] },
989
+ isFetching: true,
990
+ isFetchNextPageError: false,
991
+ isFetchingNextPage: false,
992
+ isFetchPreviousPageError: false,
993
+ isFetchingPreviousPage: true,
994
+ isRefetchError: false,
995
+ isRefetching: false,
996
+ })
997
+ // Fetch previous page failed
998
+ expect(states[3]).toMatchObject({
999
+ data: { pages: [10] },
1000
+ isFetching: false,
1001
+ isFetchNextPageError: false,
1002
+ isFetchingNextPage: false,
1003
+ isFetchPreviousPageError: true,
1004
+ isFetchingPreviousPage: false,
1005
+ isRefetchError: false,
1006
+ isRefetching: false,
1007
+ })
1008
+ })
1009
+
682
1010
  it('should silently cancel any ongoing fetch when fetching more', async () => {
683
1011
  const key = queryKey()
684
1012
  const states: Array<
@@ -8,9 +8,7 @@ describe('useMutationState', () => {
8
8
  filters: { status: 'pending' },
9
9
  }))
10
10
 
11
- expectTypeOf(result()).toEqualTypeOf<
12
- Array<MutationState<unknown, Error, void, unknown>>
13
- >()
11
+ expectTypeOf(result()).toEqualTypeOf<Array<MutationState>>()
14
12
  })
15
13
  it('should infer with select', () => {
16
14
  const result = useMutationState(() => ({
@@ -2,7 +2,6 @@ import { createEffect, createMemo, createSignal, onCleanup } from 'solid-js'
2
2
  import { replaceEqualDeep } from '@tanstack/query-core'
3
3
  import { useQueryClient } from './QueryClientProvider'
4
4
  import type {
5
- DefaultError,
6
5
  Mutation,
7
6
  MutationCache,
8
7
  MutationFilters,
@@ -13,9 +12,7 @@ import type { QueryClient } from './QueryClient'
13
12
 
14
13
  type MutationStateOptions<TResult = MutationState> = {
15
14
  filters?: MutationFilters
16
- select?: (
17
- mutation: Mutation<unknown, DefaultError, unknown, unknown>,
18
- ) => TResult
15
+ select?: (mutation: Mutation) => TResult
19
16
  }
20
17
 
21
18
  function getResult<TResult = MutationState>(
@@ -26,11 +23,7 @@ function getResult<TResult = MutationState>(
26
23
  .findAll(options.filters)
27
24
  .map(
28
25
  (mutation): TResult =>
29
- (options.select
30
- ? options.select(
31
- mutation as Mutation<unknown, DefaultError, unknown, unknown>,
32
- )
33
- : mutation.state) as TResult,
26
+ (options.select ? options.select(mutation) : mutation.state) as TResult,
34
27
  )
35
28
  }
36
29