33import warnings
44from abc import ABC , abstractmethod
55from pathlib import Path
6- from typing import TYPE_CHECKING , Awaitable , Callable , Literal , NoReturn
6+ from typing import TYPE_CHECKING , Awaitable , Callable , Literal
77
88from .._utils import AsyncCallbacks , CancelCallback , wrap_async
99from ._button import BOOKMARK_ID
@@ -122,26 +122,6 @@ def _restore_context(self) -> RestoreContext | None:
122122 """
123123 ...
124124
125- @abstractmethod
126- def _set_restore_context (self , restore_context : RestoreContext ):
127- """
128- Set the session's RestoreContext object.
129-
130- This should only be done within the `init` websocket message.
131- """
132- ...
133-
134- def _get_bookmark_exclude (self ) -> list [str ]:
135- """
136- Get the list of inputs excluded from being bookmarked.
137- """
138-
139- scoped_excludes : list [str ] = []
140- for proxy_exclude_fn in self ._on_get_exclude :
141- scoped_excludes .extend (proxy_exclude_fn ())
142- # Remove duplicates
143- return list (set ([* self .exclude , * scoped_excludes ]))
144-
145125 # # TODO: Barret - Implement this?!?
146126 # @abstractmethod
147127 # async def get_url(self) -> str:
@@ -156,16 +136,6 @@ def _get_bookmark_exclude(self) -> list[str]:
156136
157137 # await session.insert_ui(modal_with_url(url))
158138
159- @abstractmethod
160- def _create_effects (self ) -> None :
161- """
162- Create the effects for the bookmarking system.
163-
164- This method should be called when the session is created after the initial inputs have been set.
165- """
166- ...
167-
168- @abstractmethod
169139 def on_bookmark (
170140 self ,
171141 callback : (
@@ -185,9 +155,8 @@ def on_bookmark(
185155 This method should accept a single argument, which is a
186156 :class:`~shiny.bookmark._bookmark.ShinySaveState` object.
187157 """
188- ...
158+ return self . _on_bookmark_callbacks . register ( wrap_async ( callback ))
189159
190- @abstractmethod
191160 def on_bookmarked (
192161 self ,
193162 callback : Callable [[str ], None ] | Callable [[str ], Awaitable [None ]],
@@ -204,7 +173,33 @@ def on_bookmarked(
204173 The callback function to call when the session is bookmarked.
205174 This method should accept a single argument, the string representing the query parameter component of the URL.
206175 """
207- ...
176+ return self ._on_bookmarked_callbacks .register (wrap_async (callback ))
177+
178+ def on_restore (
179+ self ,
180+ callback : (
181+ Callable [[RestoreState ], None ] | Callable [[RestoreState ], Awaitable [None ]]
182+ ),
183+ ) -> CancelCallback :
184+ """
185+ Registers a function that will be called just before restoring state.
186+
187+ This callback will be executed **before** the bookmark state is restored.
188+ """
189+ return self ._on_restore_callbacks .register (wrap_async (callback ))
190+
191+ def on_restored (
192+ self ,
193+ callback : (
194+ Callable [[RestoreState ], None ] | Callable [[RestoreState ], Awaitable [None ]]
195+ ),
196+ ) -> CancelCallback :
197+ """
198+ Registers a function that will be called just after restoring state.
199+
200+ This callback will be executed **after** the bookmark state is restored.
201+ """
202+ return self ._on_restored_callbacks .register (wrap_async (callback ))
208203
209204 @abstractmethod
210205 async def update_query_string (
@@ -237,34 +232,6 @@ async def do_bookmark(self) -> None:
237232 """
238233 ...
239234
240- @abstractmethod
241- def on_restore (
242- self ,
243- callback : (
244- Callable [[RestoreState ], None ] | Callable [[RestoreState ], Awaitable [None ]]
245- ),
246- ) -> CancelCallback :
247- """
248- Registers a function that will be called just before restoring state.
249-
250- This callback will be executed **before** the bookmark state is restored.
251- """
252- ...
253-
254- @abstractmethod
255- def on_restored (
256- self ,
257- callback : (
258- Callable [[RestoreState ], None ] | Callable [[RestoreState ], Awaitable [None ]]
259- ),
260- ) -> CancelCallback :
261- """
262- Registers a function that will be called just after restoring state.
263-
264- This callback will be executed **after** the bookmark state is restored.
265- """
266- ...
267-
268235
269236class BookmarkApp (Bookmark ):
270237 _session : AppSession
@@ -288,25 +255,19 @@ def __init__(self, session: AppSession):
288255 # Making this a read only property as app authors will not be able to change how the session is restored as the server function will run after the session has been restored.
289256 @property
290257 def store (self ) -> BookmarkStore :
291- """
292- App's bookmark store value
293-
294- Possible values:
295- * `"url"`: Save / reload the bookmark state in the URL.
296- * `"server"`: Save / reload the bookmark state on the server.
297- * `"disable"` (default): Bookmarking is diabled.
298- """
299258
300259 return self ._session .app .bookmark_store
301260
302261 @property
303262 def _restore_context (self ) -> RestoreContext | None :
304- """
305- A read-only value of the session's RestoreContext object.
306- """
307263 return self ._restore_context_value
308264
309265 def _set_restore_context (self , restore_context : RestoreContext ):
266+ """
267+ Set the session's RestoreContext object.
268+
269+ This should only be done within the `init` websocket message.
270+ """
310271 self ._restore_context_value = restore_context
311272
312273 def _create_effects (self ) -> None :
@@ -448,6 +409,17 @@ async def update_query_string(
448409 }
449410 )
450411
412+ def _get_bookmark_exclude (self ) -> list [str ]:
413+ """
414+ Get the list of inputs excluded from being bookmarked.
415+ """
416+
417+ scoped_excludes : list [str ] = []
418+ for proxy_exclude_fn in self ._on_get_exclude :
419+ scoped_excludes .extend (proxy_exclude_fn ())
420+ # Remove duplicates
421+ return list (set ([* self .exclude , * scoped_excludes ]))
422+
451423 async def do_bookmark (self ) -> None :
452424
453425 if self .store == "disable" :
@@ -552,9 +524,7 @@ def __init__(self, session_proxy: SessionProxy):
552524
553525 # The goal of this method is to save the scope's values. All namespaced inputs
554526 # will already exist within the `root_state`.
555- @self ._session ._parent .bookmark .on_bookmark
556- async def scoped_on_bookmark (root_state : BookmarkState ) -> None :
557- return await self ._scoped_on_bookmark (root_state )
527+ self ._session ._parent .bookmark .on_bookmark (self ._scoped_on_bookmark )
558528
559529 from ..session import session_context
560530
@@ -633,32 +603,6 @@ def store(self) -> BookmarkStore:
633603 def _restore_context (self ) -> RestoreContext | None :
634604 return self ._session ._parent .bookmark ._restore_context
635605
636- def _set_restore_context (self , restore_context : RestoreContext ) -> NoReturn :
637- raise NotImplementedError (
638- "The `RestoreContext` should only be set on the root session object."
639- )
640-
641- def _create_effects (self ) -> NoReturn :
642- raise NotImplementedError (
643- "Please call `._create_effects()` from the root session only."
644- )
645-
646- def on_bookmark (
647- self ,
648- callback : (
649- Callable [[BookmarkState ], None ] | Callable [[BookmarkState ], Awaitable [None ]]
650- ),
651- / ,
652- ) -> CancelCallback :
653- return self ._on_bookmark_callbacks .register (wrap_async (callback ))
654-
655- def on_bookmarked (
656- self ,
657- callback : Callable [[str ], None ] | Callable [[str ], Awaitable [None ]],
658- / ,
659- ) -> CancelCallback :
660- return self ._on_bookmarked_callbacks .register (wrap_async (callback ))
661-
662606 async def update_query_string (
663607 self , query_string : str , mode : Literal ["replace" , "push" ] = "replace"
664608 ) -> None :
@@ -667,22 +611,6 @@ async def update_query_string(
667611 async def do_bookmark (self ) -> None :
668612 await self ._session ._parent .bookmark .do_bookmark ()
669613
670- def on_restore (
671- self ,
672- callback : (
673- Callable [[RestoreState ], None ] | Callable [[RestoreState ], Awaitable [None ]]
674- ),
675- ) -> CancelCallback :
676- return self ._on_restore_callbacks .register (wrap_async (callback ))
677-
678- def on_restored (
679- self ,
680- callback : (
681- Callable [[RestoreState ], None ] | Callable [[RestoreState ], Awaitable [None ]]
682- ),
683- ) -> CancelCallback :
684- return self ._on_restored_callbacks .register (wrap_async (callback ))
685-
686614
687615class BookmarkExpressStub (Bookmark ):
688616
@@ -692,24 +620,16 @@ def __init__(self, session: ExpressStubSession) -> None:
692620 from ..express ._stub_session import ExpressStubSession
693621
694622 assert isinstance (session , ExpressStubSession )
695- # self._session = session
696623
697624 @property
698625 def store (self ) -> BookmarkStore :
699626 return "disable"
700627
701628 @property
702629 def _restore_context (self ) -> RestoreContext | None :
630+ # no-op within ExpressStub
703631 return None
704632
705- def _set_restore_context (self , restore_context : RestoreContext ) -> None :
706- return None
707-
708- def _create_effects (self ) -> NoReturn :
709- raise NotImplementedError (
710- "Please call `._create_effects()` only from a real session object"
711- )
712-
713633 def on_bookmark (
714634 self ,
715635 callback : (
@@ -729,9 +649,11 @@ def on_bookmarked(
729649 async def update_query_string (
730650 self , query_string : str , mode : Literal ["replace" , "push" ] = "replace"
731651 ) -> None :
652+ # no-op within ExpressStub
732653 return None
733654
734655 async def do_bookmark (self ) -> None :
656+ # no-op within ExpressStub
735657 return None
736658
737659 def on_restore (
0 commit comments