15
15
if TYPE_CHECKING :
16
16
from ..express ._stub_session import ExpressStubSession
17
17
from ..module import ResolvedId
18
- from ..session ._session import AppSession , SessionProxy
18
+ from ..session ._session import AppSession , Session , SessionProxy
19
19
from . import RestoreContext
20
20
else :
21
21
from typing import Any
22
22
23
23
RestoreContext = Any
24
24
SessionProxy = Any
25
+ Session = Any
25
26
AppSession = Any
26
27
ResolvedId = Any
27
28
ExpressStubSession = Any
@@ -217,22 +218,26 @@ async def do_bookmark(self) -> None:
217
218
218
219
219
220
class BookmarkApp (Bookmark ):
220
- _session : AppSession
221
+ _root_session : AppSession
221
222
"""
222
- The root session object (most likely a `AppSession` object) .
223
+ The root session object.
223
224
"""
225
+
224
226
_restore_context_value : RestoreContext
225
227
"""
226
228
Placeholder value that should only be manually set within the session's `init` websocket message.
227
229
"""
228
230
229
- def __init__ (self , session : AppSession ):
231
+ def __init__ (self , root_session : AppSession ):
230
232
from ..session ._session import AppSession
231
233
232
- assert isinstance (session , AppSession )
234
+ assert isinstance (root_session , AppSession )
233
235
super ().__init__ ()
234
236
235
- self ._session = session
237
+ self ._root_session = root_session
238
+
239
+ # # Do not set it to avoid supporting a `None` type.
240
+ # # Instead, only use it after it's been set.
236
241
# self._restore_context_value = None
237
242
238
243
# Making this a read only property as app authors will not be able to change how the
@@ -241,7 +246,7 @@ def __init__(self, session: AppSession):
241
246
@property
242
247
def store (self ) -> BookmarkStore :
243
248
244
- return self ._session .app .bookmark_store
249
+ return self ._root_session .app .bookmark_store
245
250
246
251
@property
247
252
def _restore_context (self ) -> RestoreContext | None :
@@ -269,19 +274,19 @@ def _create_effects(self) -> None:
269
274
if self .store == "disable" :
270
275
return
271
276
272
- session = self ._session
277
+ root_session = self ._root_session
273
278
274
279
from .. import reactive
275
280
from ..session import session_context
276
281
from ..ui ._notification import notification_show
277
282
278
- with session_context (session ):
283
+ with session_context (root_session ):
279
284
280
285
# Fires when the bookmark button is clicked.
281
286
@reactive .effect
282
- @reactive .event (session .input [BOOKMARK_ID ])
287
+ @reactive .event (root_session .input [BOOKMARK_ID ])
283
288
async def _ ():
284
- await session .bookmark ()
289
+ await root_session .bookmark ()
285
290
286
291
# If there was an error initializing the current restore context, show
287
292
# notification in the client.
@@ -292,6 +297,7 @@ def init_error_message():
292
297
f"Error in RestoreContext initialization: { self ._restore_context ._init_error_msg } " ,
293
298
duration = None ,
294
299
type = "error" ,
300
+ session = root_session ,
295
301
)
296
302
297
303
# Run the on_restore function at the beginning of the flush cycle, but after
@@ -301,7 +307,7 @@ async def invoke_on_restore_callbacks():
301
307
if self ._on_restore_callbacks .count () == 0 :
302
308
return
303
309
304
- with session_context (session ):
310
+ with session_context (root_session ):
305
311
306
312
try :
307
313
# ?withLogErrors
@@ -322,12 +328,12 @@ async def invoke_on_restore_callbacks():
322
328
323
329
# Run the on_restored function after the flush cycle completes and
324
330
# information is sent to the client.
325
- @session .on_flushed
331
+ @root_session .on_flushed
326
332
async def invoke_on_restored_callbacks ():
327
333
if self ._on_restored_callbacks .count () == 0 :
328
334
return
329
335
330
- with session_context (session ):
336
+ with session_context (root_session ):
331
337
try :
332
338
with reactive .isolate ():
333
339
if self ._restore_context and self ._restore_context .active :
@@ -385,7 +391,7 @@ async def update_query_string(
385
391
) -> None :
386
392
if mode not in {"replace" , "push" }:
387
393
raise ValueError (f"Invalid mode: { mode } " )
388
- await self ._session ._send_message (
394
+ await self ._root_session ._send_message (
389
395
{
390
396
"updateQueryString" : {
391
397
"queryString" : query_string ,
@@ -414,17 +420,17 @@ async def get_bookmark_url(self) -> str | None:
414
420
from ..session import session_context
415
421
416
422
async def root_state_on_save (state : BookmarkState ) -> None :
417
- with session_context (self ._session ):
423
+ with session_context (self ._root_session ):
418
424
await self ._on_bookmark_callbacks .invoke (state )
419
425
420
426
root_state = BookmarkState (
421
- input = self ._session .input ,
427
+ input = self ._root_session .input ,
422
428
exclude = self ._get_bookmark_exclude (),
423
429
on_save = root_state_on_save ,
424
430
)
425
431
426
432
if self .store == "server" :
427
- query_string = await root_state ._save_state (app = self ._session .app )
433
+ query_string = await root_state ._save_state (app = self ._root_session .app )
428
434
elif self .store == "url" :
429
435
query_string = await root_state ._encode_state ()
430
436
# # Can we have browser storage?
@@ -436,7 +442,7 @@ async def root_state_on_save(state: BookmarkState) -> None:
436
442
else :
437
443
raise ValueError ("Unknown bookmark store: " + self .store )
438
444
439
- clientdata = self ._session .clientdata
445
+ clientdata = self ._root_session .clientdata
440
446
441
447
port = str (clientdata .url_port ())
442
448
full_url = "" .join (
@@ -477,7 +483,7 @@ async def do_bookmark(self) -> None:
477
483
# If on_bookmarked callback was provided, invoke it; if not call
478
484
# the default.
479
485
if self ._on_bookmarked_callbacks .count () > 0 :
480
- with session_context (self ._session ):
486
+ with session_context (self ._root_session ):
481
487
await self ._on_bookmarked_callbacks .invoke (full_url )
482
488
else :
483
489
# `session.bookmark.show_modal(url)`
@@ -497,7 +503,12 @@ async def do_bookmark(self) -> None:
497
503
class BookmarkProxy (Bookmark ):
498
504
499
505
_ns : ResolvedId
500
- _session : SessionProxy
506
+ _proxy_session : SessionProxy
507
+ _root_session : Session
508
+
509
+ @property
510
+ def _root_bookmark (self ) -> Bookmark :
511
+ return self ._root_session .bookmark
501
512
502
513
def __init__ (self , session_proxy : SessionProxy ):
503
514
from ..session ._session import SessionProxy
@@ -506,10 +517,11 @@ def __init__(self, session_proxy: SessionProxy):
506
517
super ().__init__ ()
507
518
508
519
self ._ns = session_proxy .ns
509
- self ._session = session_proxy
520
+ self ._proxy_session = session_proxy
521
+ self ._root_session = session_proxy ._root_session
510
522
511
523
# Maybe `._get_bookmark_exclude()` should be used instead of`proxy_exclude_fns`?
512
- self ._session . _parent . bookmark ._on_get_exclude .append (
524
+ self ._root_bookmark ._on_get_exclude .append (
513
525
lambda : [str (self ._ns (name )) for name in self .exclude ]
514
526
)
515
527
@@ -519,37 +531,37 @@ def __init__(self, session_proxy: SessionProxy):
519
531
520
532
# The goal of this method is to save the scope's values. All namespaced inputs
521
533
# will already exist within the `root_state`.
522
- self ._session . _parent . bookmark .on_bookmark (self ._scoped_on_bookmark )
534
+ self ._root_bookmark .on_bookmark (self ._scoped_on_bookmark )
523
535
524
536
from ..session import session_context
525
537
526
- @self ._session . _parent . bookmark .on_bookmarked
538
+ @self ._root_bookmark .on_bookmarked
527
539
async def scoped_on_bookmarked (url : str ) -> None :
528
540
if self ._on_bookmarked_callbacks .count () == 0 :
529
541
return
530
542
531
- with session_context (self ._session ):
543
+ with session_context (self ._proxy_session ):
532
544
await self ._on_bookmarked_callbacks .invoke (url )
533
545
534
546
ns_prefix = str (self ._ns + self ._ns ._sep )
535
547
536
- @self ._session . _parent . bookmark .on_restore
548
+ @self ._root_bookmark .on_restore
537
549
async def scoped_on_restore (restore_state : RestoreState ) -> None :
538
550
if self ._on_restore_callbacks .count () == 0 :
539
551
return
540
552
541
553
scoped_restore_state = restore_state ._state_within_namespace (ns_prefix )
542
554
543
- with session_context (self ._session ):
555
+ with session_context (self ._proxy_session ):
544
556
await self ._on_restore_callbacks .invoke (scoped_restore_state )
545
557
546
- @self ._session . _parent . bookmark .on_restored
558
+ @self ._root_bookmark .on_restored
547
559
async def scoped_on_restored (restore_state : RestoreState ) -> None :
548
560
if self ._on_restored_callbacks .count () == 0 :
549
561
return
550
562
551
563
scoped_restore_state = restore_state ._state_within_namespace (ns_prefix )
552
- with session_context (self ._session ):
564
+ with session_context (self ._proxy_session ):
553
565
await self ._on_restored_callbacks .invoke (scoped_restore_state )
554
566
555
567
async def _scoped_on_bookmark (self , root_state : BookmarkState ) -> None :
@@ -560,7 +572,7 @@ async def _scoped_on_bookmark(self, root_state: BookmarkState) -> None:
560
572
from ..bookmark ._bookmark import BookmarkState
561
573
562
574
scoped_state = BookmarkState (
563
- input = self ._session .input ,
575
+ input = self ._proxy_session .input ,
564
576
exclude = self .exclude ,
565
577
on_save = None ,
566
578
)
@@ -580,7 +592,7 @@ async def _scoped_on_bookmark(self, root_state: BookmarkState) -> None:
580
592
# Invoke the callback on the scopeState object
581
593
from ..session import session_context
582
594
583
- with session_context (self ._session ):
595
+ with session_context (self ._proxy_session ):
584
596
await self ._on_bookmark_callbacks .invoke (scoped_state )
585
597
586
598
# Copy `values` from scoped_state to root_state (adding namespace)
@@ -592,22 +604,22 @@ async def _scoped_on_bookmark(self, root_state: BookmarkState) -> None:
592
604
593
605
@property
594
606
def store (self ) -> BookmarkStore :
595
- return self ._session . _parent . bookmark .store
607
+ return self ._root_bookmark .store
596
608
597
609
@property
598
610
def _restore_context (self ) -> RestoreContext | None :
599
- return self ._session . _parent . bookmark ._restore_context
611
+ return self ._root_bookmark ._restore_context
600
612
601
613
async def update_query_string (
602
614
self , query_string : str , mode : Literal ["replace" , "push" ] = "replace"
603
615
) -> None :
604
- await self ._session . _parent . bookmark .update_query_string (query_string , mode )
616
+ await self ._root_bookmark .update_query_string (query_string , mode )
605
617
606
618
async def get_bookmark_url (self ) -> str | None :
607
- return await self ._session . _parent . bookmark .get_bookmark_url ()
619
+ return await self ._root_bookmark .get_bookmark_url ()
608
620
609
621
async def do_bookmark (self ) -> None :
610
- await self ._session . _parent . bookmark .do_bookmark ()
622
+ await self ._root_bookmark .do_bookmark ()
611
623
612
624
613
625
class BookmarkExpressStub (Bookmark ):
0 commit comments