11import { QueryCache , QueryClient , createQuery } from '@tanstack/svelte-query'
2- import { promiseWithResolvers , withEffectRoot } from './utils.svelte'
2+ import { promiseWithResolvers , sleep , withEffectRoot } from './utils.svelte'
33import type {
44 CreateQueryOptions ,
55 CreateQueryResult ,
@@ -887,7 +887,7 @@ describe('createQuery', () => {
887887 } ) ,
888888 )
889889
890- it . only (
890+ it (
891891 'keeps up-to-date with query key changes' ,
892892 withEffectRoot ( async ( ) => {
893893 let search = $state ( '' )
@@ -909,4 +909,212 @@ describe('createQuery', () => {
909909 await vi . waitFor ( ( ) => expect ( query . data ) . toBe ( 'phone' ) )
910910 } ) ,
911911 )
912+
913+ it (
914+ 'should create a new query when refetching a removed query' ,
915+ withEffectRoot ( async ( ) => {
916+ const key = [ 'test' ]
917+ const states : Array < CreateQueryResult < number > > = [ ]
918+ let count = 0
919+
920+ const query = $derived (
921+ createQuery (
922+ {
923+ queryKey : key ,
924+ queryFn : ( ) => Promise . resolve ( ++ count ) ,
925+ } ,
926+ queryClient ,
927+ ) ,
928+ )
929+
930+ $effect ( ( ) => {
931+ states . push ( { ...query } )
932+ } )
933+
934+ await vi . waitFor ( ( ) => {
935+ expect ( query . data ) . toBe ( 1 )
936+ } )
937+
938+ queryClient . removeQueries ( { queryKey : key } )
939+ await query . refetch ( )
940+ await vi . waitFor ( ( ) => {
941+ expect ( query . data ) . toBe ( 2 )
942+ } )
943+
944+ expect ( states . length ) . toBe ( 4 )
945+ // Initial
946+ expect ( states [ 0 ] ) . toMatchObject ( { data : undefined , dataUpdatedAt : 0 } )
947+ // Fetched
948+ expect ( states [ 1 ] ) . toMatchObject ( { data : 1 } )
949+ // Switch
950+ expect ( states [ 2 ] ) . toMatchObject ( { data : undefined , dataUpdatedAt : 0 } )
951+ // Fetched
952+ expect ( states [ 3 ] ) . toMatchObject ( { data : 2 } )
953+ } ) ,
954+ )
955+
956+ it (
957+ 'should share equal data structures between query results' ,
958+ withEffectRoot ( async ( ) => {
959+ const key = [ 'test' ]
960+
961+ const result1 = [
962+ { id : '1' , done : false } ,
963+ { id : '2' , done : false } ,
964+ ]
965+
966+ const result2 = [
967+ { id : '1' , done : false } ,
968+ { id : '2' , done : true } ,
969+ ]
970+
971+ const states : Array < CreateQueryResult < typeof result1 > > = [ ]
972+
973+ let count = 0
974+
975+ const query = $derived (
976+ createQuery < typeof result1 > (
977+ {
978+ queryKey : key ,
979+ queryFn : ( ) => {
980+ count ++
981+ return Promise . resolve ( count === 1 ? result1 : result2 )
982+ } ,
983+ } ,
984+ queryClient ,
985+ ) ,
986+ )
987+
988+ $effect ( ( ) => {
989+ states . push ( { ...query } )
990+ } )
991+
992+ await vi . waitFor ( ( ) => expect ( query . data ?. [ 1 ] ?. done ) . toBe ( false ) )
993+ await query . refetch ( )
994+ await vi . waitFor ( ( ) => expect ( query . data ?. [ 1 ] ?. done ) . toBe ( true ) )
995+
996+ expect ( states . length ) . toBe ( 4 )
997+
998+ const todos = states [ 1 ] ?. data
999+ const todo1 = todos ?. [ 0 ]
1000+ const todo2 = todos ?. [ 1 ]
1001+
1002+ const newTodos = states [ 3 ] ?. data
1003+ const newTodo1 = newTodos ?. [ 0 ]
1004+ const newTodo2 = newTodos ?. [ 1 ]
1005+
1006+ expect ( todos ) . toEqual ( result1 )
1007+ expect ( newTodos ) . toEqual ( result2 )
1008+ expect ( newTodos ) . not . toBe ( todos )
1009+ expect ( newTodo1 ) . toBe ( todo1 )
1010+ expect ( newTodo2 ) . not . toBe ( todo2 )
1011+ } ) ,
1012+ )
1013+
1014+ it (
1015+ 'should share equal data structure between query results' ,
1016+ withEffectRoot ( async ( ) => {
1017+ const key = [ 'test' ]
1018+
1019+ queryClient . setQueryData ( key , 'set' )
1020+
1021+ const query = $derived (
1022+ createQuery (
1023+ {
1024+ queryKey : key ,
1025+ queryFn : ( ) => Promise . resolve ( 'fetched' ) ,
1026+ initialData : 'initial' ,
1027+ staleTime : Infinity ,
1028+ } ,
1029+ queryClient ,
1030+ ) ,
1031+ )
1032+
1033+ await vi . waitFor ( ( ) => expect ( query . data ) . toBe ( 'set' ) )
1034+ queryClient . refetchQueries ( { queryKey : key } )
1035+ await vi . waitFor ( ( ) => expect ( query . data ) . toBe ( 'fetched' ) )
1036+ } ) ,
1037+ )
1038+
1039+ it (
1040+ 'should update query stale state and refetch when invalidated with invalidateQueries' ,
1041+ withEffectRoot ( async ( ) => {
1042+ const key = [ 'test' ]
1043+ let count = 0
1044+
1045+ const query = $derived (
1046+ createQuery < number > (
1047+ {
1048+ queryKey : key ,
1049+ queryFn : ( ) => Promise . resolve ( ++ count ) ,
1050+ staleTime : Infinity ,
1051+ } ,
1052+ queryClient ,
1053+ ) ,
1054+ )
1055+
1056+ await vi . waitFor ( ( ) =>
1057+ expect ( query ) . toEqual (
1058+ expect . objectContaining ( {
1059+ data : 1 ,
1060+ isStale : false ,
1061+ isFetching : false ,
1062+ } ) ,
1063+ ) ,
1064+ )
1065+ queryClient . invalidateQueries ( { queryKey : key } )
1066+ await vi . waitFor ( ( ) =>
1067+ expect ( query ) . toEqual (
1068+ expect . objectContaining ( {
1069+ data : 1 ,
1070+ isStale : true ,
1071+ isFetching : true ,
1072+ } ) ,
1073+ ) ,
1074+ )
1075+ await vi . waitFor ( ( ) =>
1076+ expect ( query ) . toEqual (
1077+ expect . objectContaining ( {
1078+ data : 2 ,
1079+ isStale : false ,
1080+ isFetching : false ,
1081+ } ) ,
1082+ ) ,
1083+ )
1084+ } ) ,
1085+ )
1086+
1087+ it (
1088+ 'should not update disabled query when refetching with refetchQueries' ,
1089+ withEffectRoot ( async ( ) => {
1090+ const key = [ 'test' ]
1091+ const states : Array < CreateQueryResult < number > > = [ ]
1092+ let count = 0
1093+
1094+ const query = $derived (
1095+ createQuery < number > (
1096+ {
1097+ queryKey : key ,
1098+ queryFn : ( ) => Promise . resolve ( ++ count ) ,
1099+ enabled : false ,
1100+ } ,
1101+ queryClient ,
1102+ ) ,
1103+ )
1104+
1105+ $effect ( ( ) => {
1106+ states . push ( { ...query } )
1107+ } )
1108+
1109+ await sleep ( 50 )
1110+
1111+ expect ( states . length ) . toBe ( 1 )
1112+ expect ( states [ 0 ] ) . toMatchObject ( {
1113+ data : undefined ,
1114+ isSuccess : false ,
1115+ isFetching : false ,
1116+ isStale : false ,
1117+ } )
1118+ } ) ,
1119+ )
9121120} )
0 commit comments