Skip to content

Commit

Permalink
feat: added examples for and finalized idb wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
arctic-hen7 committed Jan 24, 2022
1 parent c7d20e6 commit 362d5ca
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 5 deletions.
1 change: 1 addition & 0 deletions examples/rx_state/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
ureq = "2"
reqwasm = "0.4"
wasm-bindgen-futures = "0.4"
58 changes: 55 additions & 3 deletions examples/rx_state/src/idb.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use perseus::state::IdbFrozenStateStore;
use perseus::state::{Freeze, IdbFrozenStateStore, PageThawPrefs, ThawPrefs};
use perseus::{Html, RenderFnResultWithCause, Template};
use sycamore::prelude::*;

Expand All @@ -11,8 +11,9 @@ pub struct TestProps {
#[perseus::template_rx(IdbPage)]
pub fn idb_page(TestPropsRx { username }: TestPropsRx) -> View<G> {
let username_2 = username.clone(); // This is necessary until Sycamore's new reactive primitives are released
// TODO Futures etc.
let _idb_store = IdbFrozenStateStore::new();
let render_ctx = perseus::get_render_ctx!(); // We get the render context out here, it's not accessible in the future
let freeze_status = Signal::new(String::new()); // This isn't part of the template's data model, it's just here for demonstration
let thaw_status = Signal::new(String::new());

view! {
p { (format!("Greetings, {}!", username.get())) }
Expand All @@ -22,6 +23,57 @@ pub fn idb_page(TestPropsRx { username }: TestPropsRx) -> View<G> {
a(href = "about") { "About" }
a(href = "") { "Index" }

button(on:click = cloned!(freeze_status, render_ctx => move |_|
// The IndexedDB API is asynchronous, so we'll spawn a future
wasm_bindgen_futures::spawn_local(cloned!(render_ctx, freeze_status => async move {
// We do this here (rather than when we get the render context) so that it's updated whenever we press the button
let frozen_state = render_ctx.freeze();
let idb_store = match IdbFrozenStateStore::new().await {
Ok(idb_store) => idb_store,
Err(_) => {
freeze_status.set("Error.".to_string());
return;
}
};
match idb_store.set(&frozen_state).await {
Ok(_) => freeze_status.set("Saved.".to_string()),
Err(_) => freeze_status.set("Error.".to_string())
};
}))
)) { "Freeze to IndexedDB" }
p { (freeze_status.get()) }

button(on:click = cloned!(thaw_status, render_ctx => move |_|
// The IndexedDB API is asynchronous, so we'll spawn a future
wasm_bindgen_futures::spawn_local(cloned!(render_ctx, thaw_status => async move {
let idb_store = match IdbFrozenStateStore::new().await {
Ok(idb_store) => idb_store,
Err(_) => {
thaw_status.set("Error.".to_string());
return;
}
};
let frozen_state = match idb_store.get().await {
Ok(Some(frozen_state)) => frozen_state,
Ok(None) => {
thaw_status.set("No state stored.".to_string());
return;
}
Err(_) => {
thaw_status.set("Error.".to_string());
return;
}
};

// You would probably set your thawing preferences differently
match render_ctx.thaw(&frozen_state, ThawPrefs { page: PageThawPrefs::IncludeAll, global_prefer_frozen: true }) {
Ok(_) => thaw_status.set("Thawed.".to_string()),
Err(_) => thaw_status.set("Error.".to_string())
}
}))
)) { "Thaw from IndexedDB" }
p { (thaw_status.get()) }

// button(on:click = cloned!(frozen_app, render_ctx => move |_| {
// frozen_app.set(render_ctx.freeze());
// })) { "Freeze!" }
Expand Down
2 changes: 1 addition & 1 deletion packages/perseus/src/state/freeze_idb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl IdbFrozenStateStore {
.add_object_store(
// We'll store many versions of frozen state so that the user can revert to previous states
ObjectStore::new("frozen_state")
.key_path("id")
// We don't provide a key path because that would lock us in to storing only JS objects, and we want to store strings
.auto_increment(true), // IndexedDB doesn't need us to register value types, only things that should be indexed (gotta love JS type safety haven't you!)
)
.build()
Expand Down
2 changes: 1 addition & 1 deletion packages/perseus/src/state/rx_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub trait Freeze {
// initialized, but that means it's unmodified from the server, so there would be no point in freezing it (just as there'd be no point in freezing the router state).
impl Freeze for Option<()> {
fn freeze(&self) -> String {
serde_json::to_string(&Option::<()>::None).unwrap()
"None".to_string()
}
}

Expand Down

0 comments on commit 362d5ca

Please sign in to comment.