-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(examples): added js interop example
- Loading branch information
1 parent
191d8c9
commit 766dd44
Showing
10 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dist/ | ||
target_engine/ | ||
target_wasm/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
[package] | ||
name = "perseus-example-js-interop" | ||
version = "0.4.0-beta.3" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
perseus = { path = "../../../packages/perseus", features = [ "hydrate" ] } | ||
sycamore = "=0.8.0-beta.7" | ||
serde = { version = "1", features = ["derive"] } | ||
serde_json = "1" | ||
|
||
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] | ||
fantoccini = "0.17" | ||
|
||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] | ||
tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } | ||
# This is an internal convenience crate that exposes all integrations through features for testing | ||
perseus-integration = { path = "../../../packages/perseus-integration", default-features = false } | ||
|
||
[target.'cfg(target_arch = "wasm32")'.dependencies] | ||
wasm-bindgen = "0.2" | ||
|
||
[lib] | ||
name = "lib" | ||
path = "src/lib.rs" | ||
crate-type = [ "cdylib", "rlib" ] | ||
|
||
[[bin]] | ||
name = "perseus-example-js-interop" | ||
path = "src/lib.rs" | ||
|
||
[package.metadata.wasm-pack.profile.release] | ||
wasm-opt = [ "-Oz" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
[package] | ||
name = "my-app" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
perseus = { version = "=0.4.0-beta.3", features = [ "hydrate" ] } | ||
sycamore = "=0.8.0-beta.7" | ||
serde = { version = "1", features = ["derive"] } | ||
serde_json = "1" | ||
|
||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] | ||
tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } | ||
perseus-warp = { version = "=0.4.0-beta.3", features = [ "dflt-server" ] } | ||
|
||
[target.'cfg(target_arch = "wasm32")'.dependencies] | ||
wasm-bindgen = "0.2" | ||
|
||
[lib] | ||
name = "lib" | ||
path = "src/lib.rs" | ||
crate-type = [ "cdylib", "rlib" ] | ||
|
||
[[bin]] | ||
name = "my-app" | ||
path = "src/lib.rs" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Basic Example | ||
|
||
This is a basic example of Perseus that shows the fundamentals of a slightly more advanced Perseus app. This is considered a core example because it not only contains end-to-end tests for Perseus itself, it's also the site of the development of the default Perseus engine. For that reason, the `.perseus/` directory is checked into Git here, and this is used as the single source of truth for the default engine. The reason for developing it here is to provide the context of an actual usage of Perseus, which makes a number of things easier. Then, some scripts bridge the gap to make the engine integrate into the CLI (you shouldn't have to worry about this when working in the Perseus repo as long as you're using the `bonnie dev example ...` script). | ||
|
||
Note that this example used to be more complex, illustrating features such as setting custom headers and hosting static content, though demonstrations of these have since been moved to independent examples. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// Changes some text in a specific HTML element | ||
// If possible, try to never use JS, `web-sys` will hopefully cover everything you want to do | ||
// But, sometimes, it's unavoidable, so Perseus supports interop easily | ||
export function changeMessage() { | ||
document.getElementById("message").innerHTML = "Message from JS!"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
use perseus::{ErrorPages, Html}; | ||
use sycamore::view; | ||
|
||
pub fn get_error_pages<G: Html>() -> ErrorPages<G> { | ||
let mut error_pages = ErrorPages::new(|cx, url, status, err, _| { | ||
view! { cx, | ||
p { (format!("An error with HTTP code {} occurred at '{}': '{}'.", status, url, err)) } | ||
} | ||
}); | ||
error_pages.add_page(404, |cx, _, _, _, _| { | ||
view! { cx, | ||
p { "Page not found." } | ||
} | ||
}); | ||
|
||
error_pages | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
mod error_pages; | ||
mod templates; | ||
|
||
use perseus::{Html, PerseusApp}; | ||
|
||
#[perseus::main(perseus_integration::dflt_server)] | ||
pub fn main<G: Html>() -> PerseusApp<G> { | ||
PerseusApp::new() | ||
.template(crate::templates::index::get_template) | ||
.error_pages(crate::error_pages::get_error_pages) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
use perseus::{Html, Template}; | ||
use sycamore::prelude::{view, Scope, View}; | ||
#[cfg(target_arch = "wasm32")] | ||
use wasm_bindgen::prelude::wasm_bindgen; | ||
|
||
#[perseus::template_rx] | ||
pub fn index_page<'a, G: Html>(cx: Scope<'a>) -> View<G> { | ||
view! { cx, | ||
// We'll use JS to change this message manually | ||
p(id = "message") { "Hello World!" } | ||
button(id = "change-message", on:click = |_| { | ||
#[cfg(target_arch = "wasm32")] | ||
change_message() | ||
}) { "Change message with JS" } | ||
} | ||
} | ||
|
||
pub fn get_template<G: Html>() -> Template<G> { | ||
Template::new("index").template(index_page) | ||
} | ||
|
||
// Of course, JS will only run in the browser, so this should be browser-only | ||
#[cfg(target_arch = "wasm32")] | ||
// This path should be relative to the root of your project | ||
// That file will then be hosted behind `/.perseus/` and automatically fetched as needed | ||
#[wasm_bindgen(module = "/src/changeMessage.js")] | ||
extern "C" { | ||
#[wasm_bindgen(js_name = "changeMessage")] | ||
fn change_message(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod index; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use fantoccini::{Client, Locator}; | ||
use perseus::wait_for_checkpoint; | ||
|
||
#[perseus::test] | ||
async fn main(c: &mut Client) -> Result<(), fantoccini::error::CmdError> { | ||
c.goto("http://localhost:8080").await?; | ||
wait_for_checkpoint!("begin", 0, c); | ||
let url = c.current_url().await?; | ||
assert!(url.as_ref().starts_with("http://localhost:8080")); | ||
|
||
// The greeting was passed through using build state | ||
wait_for_checkpoint!("initial_state_present", 0, c); | ||
wait_for_checkpoint!("page_visible", 0, c); | ||
let greeting = c.find(Locator::Css("p")).await?.text().await?; | ||
assert_eq!(greeting, "Hello World!"); | ||
// For some reason, retrieving the inner HTML or text of a `<title>` doens't | ||
// work | ||
let title = c.find(Locator::Css("title")).await?.html(false).await?; | ||
assert!(title.contains("Index Page")); | ||
|
||
// Go to `/about` | ||
c.find(Locator::Id("about-link")).await?.click().await?; | ||
let url = c.current_url().await?; | ||
assert!(url.as_ref().starts_with("http://localhost:8080/about")); | ||
wait_for_checkpoint!("initial_state_not_present", 0, c); | ||
wait_for_checkpoint!("page_visible", 1, c); | ||
// Make sure the hardcoded text there exists | ||
let text = c.find(Locator::Css("p")).await?.text().await?; | ||
assert_eq!(text, "About."); | ||
let title = c.find(Locator::Css("title")).await?.html(false).await?; | ||
assert!(title.contains("About Page")); | ||
// Make sure we get initial state if we refresh | ||
c.refresh().await?; | ||
wait_for_checkpoint!("initial_state_present", 0, c); | ||
|
||
Ok(()) | ||
} |