@@ -44,12 +44,21 @@ def __init__(
4444 self ._keep_previous_data = keep_previous_data
4545
4646 @override
47- def push_change (self ):
47+ def push_change (self , keep_previous_data : bool | None = None ):
4848 # Synchronously clear data before scheduling the effect to run.
4949 # This ensures renders see the loading state immediately, not stale data.
50- self ._result ._set_loading (clear_data = not self ._keep_previous_data ) # pyright: ignore[reportPrivateUsage]
50+ if keep_previous_data is None :
51+ keep_previous_data = self ._keep_previous_data
52+ self ._result .set_loading (clear_data = not keep_previous_data )
5153 super ().push_change ()
5254
55+ def refetch (self , keep_previous_data : bool | None = None ):
56+ if keep_previous_data is None :
57+ keep_previous_data = self ._keep_previous_data
58+ self .cancel ()
59+ self ._result .set_loading (clear_data = not keep_previous_data )
60+ self .run ()
61+
5362
5463class QueryResult (Generic [T ]):
5564 def __init__ (self , initial_data : T | None = None ):
@@ -63,7 +72,7 @@ def __init__(self, initial_data: T | None = None):
6372 # Tracks whether at least one load cycle completed (success or error)
6473 self ._has_loaded : Signal [bool ] = Signal (False , name = "query.has_loaded" )
6574 # Effect driving this query (attached by QueryProperty)
66- self ._effect : AsyncEffect | None = None
75+ self ._effect : QueryAsyncEffect | None = None
6776
6877 @property
6978 def is_loading (self ) -> bool :
@@ -89,39 +98,38 @@ def data(self) -> T | None:
8998 def has_loaded (self ) -> bool :
9099 return self ._has_loaded .read ()
91100
92- def attach_effect (self , effect : AsyncEffect ) -> None :
101+ def attach_effect (self , effect : QueryAsyncEffect ) -> None :
93102 self ._effect = effect
94103
95- def refetch (self ) -> None :
104+ def refetch (self , keep_previous_data : bool | None = None ) -> None :
96105 if self ._effect is None :
97106 return
98- self ._effect .cancel ()
99- self ._effect .run ()
107+ self ._effect .refetch (keep_previous_data = keep_previous_data )
100108
101109 def dispose (self ) -> None :
102110 if self ._effect is None :
103111 return
104112 self ._effect .dispose ()
105113
106114 # Internal setters used by the query machinery
107- def _set_loading (self , * , clear_data : bool = False ):
115+ def set_loading (self , * , clear_data : bool = False ):
108116 # print("[QueryResult] set loading=True")
109117 self ._is_loading .write (True )
110118 self ._is_error .write (False )
111119 self ._error .write (None )
112120 if clear_data :
113121 # If there was an explicit initial value, reset to it; otherwise clear
114- self ._data .write (self . _initial_data )
122+ self ._data .write (None )
115123
116- def _set_success (self , data : T ):
124+ def set_success (self , data : T ):
117125 # print(f"[QueryResult] set success data={data!r}")
118126 self ._data .write (data )
119127 self ._is_loading .write (False )
120128 self ._is_error .write (False )
121129 self ._error .write (None )
122130 self ._has_loaded .write (True )
123131
124- def _set_error (self , err : Exception ):
132+ def set_error (self , err : Exception ):
125133 # print(f"[QueryResult] set error err={err!r}")
126134 self ._error .write (err )
127135 self ._is_loading .write (False )
@@ -140,16 +148,6 @@ def set_initial_data(self, data: T):
140148 self ._initial_data = data
141149 self ._data .write (data )
142150
143- # Public helpers mirroring internal transitions
144- def set_loading (self , * , clear_data : bool = False ) -> None :
145- self ._set_loading (clear_data = clear_data )
146-
147- def set_success (self , data : T ) -> None :
148- self ._set_success (data )
149-
150- def set_error (self , err : Exception ) -> None :
151- self ._set_error (err )
152-
153151
154152OnSuccessFn = Callable [[TState ], Any ] | Callable [[TState , T ], Any ]
155153OnErrorFn = Callable [[TState ], Any ] | Callable [[TState , Exception ], Any ]
@@ -300,9 +298,6 @@ async def run_effect():
300298 return None
301299 inflight_key = key
302300
303- # Set loading immediately; optionally clear previous data
304- result .set_loading (clear_data = not self ._keep_previous_data )
305-
306301 try :
307302 data = await bound_fetch ()
308303 except asyncio .CancelledError :
0 commit comments