88from typing import TYPE_CHECKING , Any , Literal , Optional
99from urllib .parse import parse_qs , parse_qsl
1010
11+ from ..module import ResolvedId
1112from ._bookmark_state import local_restore_dir
1213from ._types import BookmarkRestoreDirFn
1314from ._utils import from_json_str , in_shiny_server
@@ -283,33 +284,36 @@ class RestoreInputSet:
283284 could completely prevent any other (non- restored) kvalue from being used.
284285 """
285286
286- _values : dict [str , Any ]
287- _pending : set [str ]
287+ _values : dict [ResolvedId , Any ]
288+ _pending : set [ResolvedId ]
288289 """Names of values which have been marked as pending"""
289- _used : set [str ]
290+ _used : set [ResolvedId ]
290291 """Names of values which have been used"""
291292
292293 def __init__ (self , values : Optional [dict [str , Any ]] = None ):
293294
294- self ._values = {} if values is None else values
295+ if values is None :
296+ self ._values = {}
297+ else :
298+ self ._values = {ResolvedId (key ): value for key , value in values .items ()}
295299 self ._pending = set ()
296300 self ._used = set ()
297301
298- def exists (self , name : str ) -> bool :
302+ def exists (self , name : ResolvedId ) -> bool :
299303 return name in self ._values
300304
301- def available (self , name : str ) -> bool :
305+ def available (self , name : ResolvedId ) -> bool :
302306 return self .exists (name ) and not self .is_used (name )
303307
304- def is_pending (self , name : str ) -> bool :
308+ def is_pending (self , name : ResolvedId ) -> bool :
305309 return name in self ._pending
306310
307- def is_used (self , name : str ) -> bool :
311+ def is_used (self , name : ResolvedId ) -> bool :
308312 return name in self ._used
309313
310314 # Get a value. If `force` is TRUE, get the value without checking whether
311315 # has been used, and without marking it as pending.
312- def get (self , name : str , force : bool = False ) -> Any :
316+ def get (self , name : ResolvedId , force : bool = False ) -> Any :
313317 if force :
314318 return self ._values [name ]
315319
@@ -325,7 +329,7 @@ def flush_pending(self) -> None:
325329 self ._pending .clear ()
326330
327331 def as_dict (self ) -> dict [str , Any ]:
328- return self ._values
332+ return { str ( key ): value for key , value in self ._values . items ()}
329333
330334
331335# #############################################################################
@@ -386,7 +390,7 @@ def get_current_restore_context() -> RestoreContext | None:
386390 return ctx
387391
388392
389- def restore_input (id : str , default : Any ) -> Any :
393+ def restore_input (resolved_id : ResolvedId , default : Any ) -> Any :
390394 """
391395 Restore an input value
392396
@@ -400,6 +404,10 @@ def restore_input(id: str, default: Any) -> Any:
400404 default
401405 A default value to use, if there's no value to restore.
402406 """
407+ if not isinstance (resolved_id , ResolvedId ):
408+ raise TypeError (
409+ "Expected `resolved_id` to be of type `ResolvedId` which is returned from `shiny.module.resolve_id(id)`."
410+ )
403411 # Will run even if the domain is missing
404412 if not has_current_restore_context ():
405413 return default
@@ -408,7 +416,7 @@ def restore_input(id: str, default: Any) -> Any:
408416 ctx = get_current_restore_context ()
409417 if isinstance (ctx , RestoreContext ):
410418 old_inputs = ctx .input
411- if old_inputs .available (id ):
412- return old_inputs .get (id )
419+ if old_inputs .available (resolved_id ):
420+ return old_inputs .get (resolved_id )
413421
414422 return default
0 commit comments