You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Instantiate an empty frozen app that can persist across templates (with interior mutability for possible thawing)
193
193
let frozen_app:Rc<RefCell<Option<(FrozenApp,ThawPrefs)>>> = Rc::new(RefCell::new(None));
194
+
// Set up a mutable property for whether or not this is the first load of the first page
195
+
let is_first = Rc::new(Cell::new(true));
194
196
195
197
// If we're using live reload, set up an indicator so that our listening to the WebSocket at the top-level (where we don't have the render context that we need for freezing/thawing)
196
198
// can signal the templates to perform freezing/thawing
/// An indicator `Signal` used to allow the root to instruct the app that we're about to reload because of an instruction from the live reloading server.
Copy file name to clipboardExpand all lines: packages/perseus/src/state/freeze_idb.rs
+5-1
Original file line number
Diff line number
Diff line change
@@ -56,8 +56,12 @@ impl std::fmt::Debug for IdbFrozenStateStore {
56
56
implIdbFrozenStateStore{
57
57
/// Creates a new store for this origin. If it already exists from a previous visit, the existing one will be interfaced with.
58
58
pubasyncfnnew() -> Result<Self,IdbError>{
59
+
Self::new_with_name("perseus").await
60
+
}
61
+
/// Creates a new store for this origin. If it already exists from a previous visit, the existing one will be interfaced with. This also allows the provision of a custom name for the DB.
/// Freezes the app's state to IndexedDB to be accessed in future.
6
+
// TODO Error handling
7
+
pubasyncfnhsr_freeze(render_ctx:RenderCtx){
8
+
let frozen_state = render_ctx.freeze();
9
+
// We use a custom name so we don't interfere with any state freezing the user's doing independently
10
+
let idb_store = matchIdbFrozenStateStore::new_with_name("perseus_hsr").await{
11
+
Ok(idb_store) => idb_store,
12
+
Err(_) => {
13
+
return;
14
+
}
15
+
};
16
+
match idb_store.set(&frozen_state).await{
17
+
Ok(_) => log("State frozen."),
18
+
Err(_) => {
19
+
return;
20
+
}
21
+
};
22
+
}
23
+
24
+
/// Thaws a previous state frozen in development.
25
+
// This will be run at the beginning of every template function, which means it gets executed on the server as well, so we have to Wasm-gate this
26
+
#[cfg(target_arch = "wasm32")]
27
+
// TODO Error handling
28
+
pubasyncfnhsr_thaw(render_ctx:RenderCtx){
29
+
usesuper::{PageThawPrefs,ThawPrefs};
30
+
31
+
let idb_store = matchIdbFrozenStateStore::new_with_name("perseus_hsr").await{
32
+
Ok(idb_store) => idb_store,
33
+
Err(_) => {
34
+
return;
35
+
}
36
+
};
37
+
let frozen_state = match idb_store.get().await{
38
+
Ok(Some(frozen_state)) => frozen_state,
39
+
// If there's no frozen state available, we'll proceed as usual
40
+
Ok(None) => return,
41
+
Err(_) => {
42
+
return;
43
+
}
44
+
};
45
+
46
+
// This is designed to override everything to restore the app to its previous state, so we should override everything
47
+
// This isn't problematic because the state will be frozen right before the reload and restored right after, so we literally can't miss anything (unless there's auto-typing tech involved!)
48
+
let thaw_prefs = ThawPrefs{
49
+
page:PageThawPrefs::IncludeAll,
50
+
global_prefer_frozen:true,
51
+
};
52
+
// To be absolutely clear, this will NOT fail if the user has changed their data model, it will be triggered if the state is actually corrupted
53
+
// If that's the case, we'll log it and wait for the next freeze to override the invalid stuff
54
+
// If the user has updated their data model, the macros will fail with frozen state and switch to active or generated as necessary (meaning we lose the smallest amount of state
55
+
// possible!)
56
+
match render_ctx.thaw(&frozen_state, thaw_prefs){
57
+
Ok(_) => log("State restored."),
58
+
Err(_) => log("Stored state corrupted, waiting for next code change to override."),
59
+
};
60
+
}
61
+
62
+
/// Thaws a previous state frozen in development.
63
+
#[cfg(not(target_arch = "wasm32"))]
64
+
pubasyncfnhsr_thaw(_render_ctx:RenderCtx){}
65
+
66
+
/// An internal function for logging data about HSR.
Copy file name to clipboardExpand all lines: packages/perseus/src/state/live_reload.rs
+2
Original file line number
Diff line number
Diff line change
@@ -72,6 +72,8 @@ fn log(msg: &str) {
72
72
/// Force-reloads the page. Any code after this will NOT be called, as the browser will completely reload the page, dumping your code and restarting from the beginning. This will result in
73
73
/// a total loss of all state unless it's frozen in some way.
74
74
///
75
+
/// Note that the parameter that forces the browser to bypass its cache is non-standard, and only impacts Firefox. On all other browsers, this has no effect.
76
+
///
75
77
/// # Panics
76
78
/// This will panic if it was impossible to reload (which would be caused by a *very* old browser).
/// Whether or not this page is the very first to have been rendered since the browser loaded the app. This will be reset on full reloads, and is used internally to determine whether or
/// An indicator `Signal` used to allow the root to instruct the app that we're about to reload because of an instruction from the live reloading server. Hooking into this to run code
40
40
/// before live reloading takes place is NOT supported, as no guarantee can be made that your code will run before Perseus reloads the page fully (at which point no more code will run).
0 commit comments