Skip to content

Commit 2f80153

Browse files
committed
session.do_bookmark() is functional in "url" and "server"
1 parent 5681da8 commit 2f80153

File tree

2 files changed

+300
-37
lines changed

2 files changed

+300
-37
lines changed

shiny/bookmark/_bookmark.py

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,37 @@
1414
# {values} -> dict (where as in R is an environment)
1515
# √ values is a dict!
1616
# {exclude} -> Requires `session.setBookmarkExclude(names)`, `session.getBookmarkExclude()`
17-
# * `session.setBookmarkExclude(names)` TODO:
18-
# * `session.getBookmarkExclude()`
19-
# * `session.bookmark_exclude` value?
17+
# √ `session.bookmark_exclude: list[str]` value!
18+
# √ `session._get_bookmark_exclude()` & `session._bookmark_exclude_fn`
2019
# Using a `.bookmark_exclude = []` and `._get_bookmark_exclude()` helper that accesses a `._bookmark_exclude_fns` list of functions which return scoped bookmark excluded values
2120
# Enable bookmarking hooks:
22-
# * types: `url`, `server`, `disable`
23-
# * where to store it? `session` object feels too late. `App` may not exist yet.
21+
# * √ `session.bookmark_store`: `url`, `server`, `disable`
2422
# Session hooks -> `onBookmark()`, `onBookmarked()`, `onRestore(), `onRestored()`
25-
# * `session.onBookmark()` TODO:
26-
# * `session.onBookmarked()` TODO:
23+
# * `session.on_bookmark()` # Takes the save state
24+
# * `session.on_bookmarked()` # Takes a url
2725
# * `session.onRestore()`
2826
# * `session.onRestored()`
2927
# Session hooks -> Require list of callback functions for each
30-
# Session hooks -> Calling hooks in proper locations with info
31-
# Session hook -> Call bookmark "right now": `doBookmark()`
32-
# * `session.doBookmark()`
28+
# * √ Session hooks -> Calling hooks in proper locations with info
29+
# * √ Session hook -> Call bookmark "right now": `doBookmark()`
30+
# * `session.do_bookmark()`
3331
# Session updates -> Require updates for `SessionProxy` object
34-
# `doBookmark()` -> Update query string
35-
# * Update query string
32+
# * √ `doBookmark()` -> Update query string
33+
# * Update query string
3634

3735
# bookmark -> restore state
3836
# restore state -> {inputs, values, exclude}
3937
# restore {inputs} -> Update all inputs given restored value
4038

39+
# Shinylive!
40+
# Get query string from parent frame / tab
41+
# * Ignore the code itself
42+
# * May need to escape (all?) the parameters to avoid collisions with `h=` or `code=`.
43+
# Set query string to parent frame / tab
44+
4145
import pickle
4246
from pathlib import Path
43-
from typing import Any, Callable
47+
from typing import Any, Awaitable, Callable
4448
from urllib.parse import urlencode as urllib_urlencode
4549

4650
from .. import Inputs
@@ -57,8 +61,9 @@ class ShinySaveState:
5761
input: Inputs
5862
values: dict[str, Any]
5963
exclude: list[str]
64+
# _bookmark_: A special value that is always excluded from the bookmark.
6065
on_save: (
61-
Callable[["ShinySaveState"], None] | None
66+
Callable[["ShinySaveState"], Awaitable[None]] | None
6267
) # A callback to invoke during the saving process.
6368

6469
# These are set not in initialize(), but by external functions that modify
@@ -69,20 +74,22 @@ def __init__(
6974
self,
7075
input: Inputs,
7176
exclude: list[str],
72-
on_save: Callable[["ShinySaveState"], None] | None,
77+
on_save: Callable[["ShinySaveState"], Awaitable[None]] | None,
7378
):
7479
self.input = input
7580
self.exclude = exclude
7681
self.on_save = on_save
7782
self.dir = None # This will be set by external functions.
7883
self.values = {}
7984

80-
def _call_on_save(self):
81-
# Allow user-supplied onSave function to do things like add state$values, or
85+
self._always_exclude: list[str] = ["._bookmark_"]
86+
87+
async def _call_on_save(self):
88+
# Allow user-supplied save function to do things like add state$values, or
8289
# save data to state dir.
8390
if self.on_save:
8491
with isolate():
85-
self.on_save(self)
92+
await self.on_save(self)
8693

8794
def _exclude_bookmark_value(self):
8895
# If the bookmark value is not in the exclude list, add it.
@@ -98,19 +105,19 @@ async def _save_state(self) -> str:
98105
str
99106
A query string which can be used to restore the session.
100107
"""
101-
id = private_random_id(prefix="", bytes=3)
108+
id = private_random_id(prefix="", bytes=8)
102109

103110
# TODO: barret move code to single call location
104111
# A function for saving the state object to disk, given a directory to save
105112
# to.
106113
async def save_state_to_dir(state_dir: Path) -> None:
107114
self.dir = state_dir
108115

109-
self._call_on_save()
116+
await self._call_on_save()
110117

111118
self._exclude_bookmark_value()
112119

113-
input_values_json = self.input._serialize(
120+
input_values_json = await self.input._serialize(
114121
exclude=self.exclude,
115122
state_dir=self.dir,
116123
)
@@ -165,7 +172,7 @@ async def _encode_state(self) -> str:
165172
A query string which can be used to restore the session.
166173
"""
167174
# Allow user-supplied onSave function to do things like add state$values.
168-
self._call_on_save()
175+
await self._call_on_save()
169176

170177
self._exclude_bookmark_value()
171178

0 commit comments

Comments
 (0)