@tanstack/solid-query 5.35.5 → 5.36.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.
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.0",
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.0"
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<