diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e5e102f..7c1ad60 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -54,7 +54,7 @@ jobs: - crate: glory path: crates/glory - crate: glory-cli - path: crates/glory-cli + path: crates/cli steps: - uses: dtolnay/rust-toolchain@stable with: diff --git a/Cargo.toml b/Cargo.toml index 3c6b957..f17ea9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ exclude = ["examples"] resolver = "2" [workspace.package] -version = "0.3.0" +version = "0.3.1" authors = ["Chrislearn Young "] edition = "2021" rust-version = "1.73" @@ -21,16 +21,16 @@ license = "MIT OR Apache-2.0" categories = ["web-programming::http-server", "web-programming::websocket", "network-programming", "asynchronous"] [workspace.dependencies] -glory-core = { version = "0.3.0", path = "crates/core", default-features = false }# -glory-routing = { version = "0.3.0", path = "crates/routing", default-features = false } -glory-hot-reload = { version = "0.3.0", path = "crates/hot-reload" } +glory-core = { version = "0.3.1", path = "crates/core", default-features = false }# +glory-routing = { version = "0.3.1", path = "crates/routing", default-features = false } +glory-hot-reload = { version = "0.3.1", path = "crates/hot-reload" } anyhow = "1" async-trait = "0.1.42" base64 = "0.21" cfg-if = "1" config = { version = "0.13", default-features = false, features = ["toml"] } -educe = "0.4" +educe = "0.5" form_urlencoded = "1" futures = "0.3" futures-channel = { version = "0.3", default-features = true } @@ -43,7 +43,7 @@ paste = "1" percent-encoding = "2" path-slash = "0.2" regex = "1" -salvo = { version = "0.58", default-features = true } +salvo = { version = "0.60", default-features = true } serde = { version = "1" } serde_json = { version = "1" } smallvec = "1" diff --git a/README.md b/README.md index 4e2ebba..9de3f54 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ Glory is a experimental rust web front framework modified from leptos. Your can find examples in [examples](./examples/) folder. +Online example: [http://glory.rs:8000](http://glory.rs:8000). + ## 🩸 Contributing Contributions are absolutely, positively welcome and encouraged! Contributions come in many forms. You could: diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index d1392c3..2a0679d 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -12,43 +12,43 @@ rust-version = { workspace = true } [[bin]] path = "src/main.rs" name = "glory" - # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = { version = "4.0", features = ["derive"] } -serde = { workspace = true, features = ["derive"] } +ansi_term = "0.12" anyhow = { workspace = true } -log = "0.4" -flexi_logger = "0.27" -lightningcss = { version = "1.0.0-alpha.47", features = ["browserslist"] } -salvo = { workspace = true, features = ["websocket"] } -tokio = { version = "1.4", default-features = false, features = ["full"] } -# not using notify 5.0 because it uses Crossbeam which has an issue with tokio -notify = "4" -once_cell ={ workspace = true } -which = "5.0" +async-trait = "0.1.72" +brotli = { version = "3.4", features = ["default"] } +bytes = "1.4" +camino = "1.1" cargo_metadata = { version = "0.18", features = ["builder"] } -serde_json = "1.0" -wasm-bindgen-cli-support = "0.2" -ansi_term = "0.12" - -seahash = "4.1" -reqwest = { version = "0.11", features = ["blocking", "__tls", "default-tls", "native-tls-crate", "json"], default-features = false } +clap = { version = "4.0", features = ["derive"] } +derive_more = "0.99" dirs = "5.0" -camino = "1.1" dotenvy = "0.15" -itertools = "0.11" -derive_more = "0.99" -flate2 = "1.0" -zip = { version = "0.6", default-features = false, features = ["deflate"] } -tar = "0.4" dunce = "1.0" -bytes = "1.4" +flate2 = "1.0" +flexi_logger = "0.27" # glory-hot-reload = { git = "https://github.com/glory-rs/glory", version = "0.4.8" } glory-hot-reload = { workspace = true } +itertools = "0.12" +lightningcss = { version = "1.0.0-alpha.51", features = ["browserslist"] } +log = "0.4" +# not using notify 5.0 because it uses Crossbeam which has an issue with tokio +notify = "4" +once_cell = { workspace = true } +reqwest = { version = "0.11", features = ["blocking", "__tls", "default-tls", "native-tls-crate", "json"], default-features = false } +salvo = { workspace = true, features = ["websocket"] } +seahash = "4.1" semver = "1.0.18" -async-trait = "0.1.72" +serde = { workspace = true, features = ["derive"] } +serde_json = "1.0" +tar = "0.4" +tokio = { version = "1.4", default-features = false, features = ["full"] } +wasm-bindgen-cli-support = "0.2" +which = "5.0" +zip = { version = "0.6", default-features = false, features = ["deflate"] } +zstd = { version = "0.13", features = ["default"] } [dev-dependencies] insta = { version = "1.31.0", features = ["yaml"] } @@ -56,9 +56,4 @@ temp-dir = "0.1" [features] full_tests = [] -no_downloads = [] - -# The profile that 'cargo dist' will build with -[profile.dist] -inherits = "release" -lto = "thin" +no_downloads = [] \ No newline at end of file diff --git a/crates/cli/src/compile/front.rs b/crates/cli/src/compile/front.rs index 1bcaaaf..5cd8ddc 100644 --- a/crates/cli/src/compile/front.rs +++ b/crates/cli/src/compile/front.rs @@ -1,6 +1,15 @@ use std::collections::HashMap; +use std::fs::File; +use std::io::Write; use std::sync::Arc; +use brotli::CompressorWriter; +use camino::{Utf8Path, Utf8PathBuf}; +use flate2::write::GzEncoder; +use tokio::process::Child; +use tokio::{process::Command, sync::broadcast, task::JoinHandle}; +use wasm_bindgen_cli_support::Bindgen; + use super::ChangeSet; use crate::config::Project; use crate::ext::fs; @@ -14,10 +23,6 @@ use crate::{ }, logger::GRAY, }; -use camino::{Utf8Path, Utf8PathBuf}; -use tokio::process::Child; -use tokio::{process::Command, sync::broadcast, task::JoinHandle}; -use wasm_bindgen_cli_support::Bindgen; pub async fn front(proj: &Arc, changes: &ChangeSet) -> JoinHandle>> { let proj = proj.clone(); @@ -102,6 +107,24 @@ async fn bindgen(proj: &Project) -> Result> { } } + let data = fs::read(&wasm_file.dest).await?; + let br_file = File::create(format!("{}.br", wasm_file.dest.as_str()))?; + let mut br_writer = CompressorWriter::new( + br_file, + 32 * 1024, // 32 KiB buffer + 11, // BROTLI_PARAM_QUALITY + 22, // BROTLI_PARAM_LGWIN + ); + br_writer.write_all(&data)?; + + let zstd_data = zstd::encode_all(&*data, 21)?; + let mut zstd_file = File::create(format!("{}.zst", wasm_file.dest.as_str()))?; + zstd_file.write_all(&zstd_data)?; + + let gzip_file = File::create(format!("{}.gz", wasm_file.dest.as_str()))?; + let mut gzip_encoder = GzEncoder::new(gzip_file, flate2::Compression::best()); + gzip_encoder.write_all(&data)?; + let mut js_changed = false; js_changed |= write_snippets(proj, bindgen.snippets()).await?; diff --git a/crates/cli/src/compile/style.rs b/crates/cli/src/compile/style.rs index 230df4a..5d8950d 100644 --- a/crates/cli/src/compile/style.rs +++ b/crates/cli/src/compile/style.rs @@ -85,7 +85,7 @@ fn browser_lists(query: &str) -> Result> { async fn process_css(proj: &Project, css: String) -> Result { let browsers = browser_lists(&proj.style.browser_query).context("glory.style.browser_query")?; - let mut stylesheet = StyleSheet::parse(&css, ParserOptions::default()).map_err(|e| anyhow!("{e}"))?; + let mut stylesheet = StyleSheet::parse(&css, ParserOptions::default()).map_err(|e| anyhow!("lightingcss: {e}"))?; if proj.release { stylesheet.minify(MinifyOptions::default())?; diff --git a/crates/cli/src/compile/tailwind.rs b/crates/cli/src/compile/tailwind.rs index 16e01cb..cf73551 100644 --- a/crates/cli/src/compile/tailwind.rs +++ b/crates/cli/src/compile/tailwind.rs @@ -26,7 +26,8 @@ pub async fn compile_tailwind(_proj: &Project, tw_conf: &TailwindConfig) -> Resu if done { log::info!("Tailwind finished {}", GRAY.paint(line)); - Ok(Outcome::Success(output.stdout())) + let css = std::fs::read_to_string(&tw_conf.output_file).context("read tailwind output")?; + Ok(Outcome::Success(css)) } else { log::warn!("Tailwind failed {}", GRAY.paint(line)); println!("{}\n{}", output.stdout(), output.stderr()); @@ -64,7 +65,14 @@ async fn create_default_tailwind_config(tw_conf: &TailwindConfig) -> Result<()> pub async fn tailwind_process(cmd: &str, tw_conf: &TailwindConfig) -> Result<(String, Command)> { let tailwind = Exe::Tailwind.get().await.dot()?; - let args: Vec<&str> = vec!["--input", tw_conf.input_file.as_str(), "--config", tw_conf.config_file.as_str()]; + let args: Vec<&str> = vec![ + "--input", + tw_conf.input_file.as_str(), + "--output", + tw_conf.output_file.as_str(), + "--config", + tw_conf.config_file.as_str(), + ]; let line = format!("{} {}", cmd, args.join(" ")); let mut command = Command::new(tailwind); command.args(args); diff --git a/crates/cli/src/config/tailwind.rs b/crates/cli/src/config/tailwind.rs index f97e451..b350b61 100644 --- a/crates/cli/src/config/tailwind.rs +++ b/crates/cli/src/config/tailwind.rs @@ -6,6 +6,7 @@ use anyhow::{bail, Result}; #[derive(Clone, Debug)] pub struct TailwindConfig { pub input_file: Utf8PathBuf, + pub output_file: Utf8PathBuf, pub config_file: Utf8PathBuf, } @@ -20,12 +21,20 @@ impl TailwindConfig { return Ok(None); }; + let mut output_file = Utf8PathBuf::new(); + output_file.push("target/front/"); + output_file.push(&input_file); + let config_file = conf.config_dir.join( conf.tailwind_config_file .clone() .unwrap_or_else(|| Utf8PathBuf::from("tailwind.config.js")), ); - Ok(Some(Self { input_file, config_file })) + Ok(Some(Self { + input_file, + output_file, + config_file, + })) } } diff --git a/crates/core/src/web/events/csr.rs b/crates/core/src/web/events/csr.rs index 7d6e187..10569d4 100644 --- a/crates/core/src/web/events/csr.rs +++ b/crates/core/src/web/events/csr.rs @@ -78,193 +78,7 @@ impl Custom { } } -macro_rules! generate_event_types { - {$( - $( #[$does_not_bubble:ident] )? - $event:ident : $web_sys_event:ident - ),* $(,)?} => { - - $( - #[doc = concat!("The `", stringify!($event), "` event, which receives [", stringify!($web_sys_event), "](web_sys::", stringify!($web_sys_event), ") as its argument.")] - #[derive(Copy, Clone)] - #[allow(non_camel_case_types)] - pub struct $event; - - impl EventDescriptor for $event { - type EventType = web_sys::$web_sys_event; - - fn name(&self) -> Cow<'static, str> { - stringify!($event).into() - } - - $( - generate_event_types!($does_not_bubble); - )? - } - )* - }; - - (does_not_bubble) => { - fn bubbles(&self) -> bool { false } - } -} - -generate_event_types! { - // ========================================================= - // WindowEventHandlersEventMap - // ========================================================= - afterprint: Event, - beforeprint: Event, - beforeunload: BeforeUnloadEvent, - gamepadconnected: GamepadEvent, - gamepaddisconnected: GamepadEvent, - hashchange: HashChangeEvent, - languagechange: Event, - message: MessageEvent, - messageerror: MessageEvent, - offline: Event, - online: Event, - pagehide: PageTransitionEvent, - pageshow: PageTransitionEvent, - popstate: PopStateEvent, - rejectionhandled: PromiseRejectionEvent, - storage: StorageEvent, - unhandledrejection: PromiseRejectionEvent, - #[does_not_bubble] - unload: Event, - - // ========================================================= - // GlobalEventHandlersEventMap - // ========================================================= - #[does_not_bubble] - abort: UiEvent, - animationcancel: AnimationEvent, - animationend: AnimationEvent, - animationiteration: AnimationEvent, - animationstart: AnimationEvent, - auxclick: MouseEvent, - beforeinput: InputEvent, - #[does_not_bubble] - blur: FocusEvent, - canplay: Event, - canplaythrough: Event, - change: Event, - click: MouseEvent, - #[does_not_bubble] - close: Event, - compositionend: CompositionEvent, - compositionstart: CompositionEvent, - compositionupdate: CompositionEvent, - contextmenu: MouseEvent, - cuechange: Event, - dblclick: MouseEvent, - drag: DragEvent, - dragend: DragEvent, - dragenter: DragEvent, - dragleave: DragEvent, - dragover: DragEvent, - dragstart: DragEvent, - drop: DragEvent, - durationchange: Event, - emptied: Event, - ended: Event, - #[does_not_bubble] - error: ErrorEvent, - #[does_not_bubble] - focus: FocusEvent, - #[does_not_bubble] - focusin: FocusEvent, - #[does_not_bubble] - focusout: FocusEvent, - formdata: Event, // web_sys does not include `FormDataEvent` - gotpointercapture: PointerEvent, - input: Event, - invalid: Event, - keydown: KeyboardEvent, - keypress: KeyboardEvent, - keyup: KeyboardEvent, - #[does_not_bubble] - load: Event, - loadeddata: Event, - loadedmetadata: Event, - #[does_not_bubble] - loadstart: Event, - lostpointercapture: PointerEvent, - mousedown: MouseEvent, - mouseenter: MouseEvent, - mouseleave: MouseEvent, - mousemove: MouseEvent, - mouseout: MouseEvent, - mouseover: MouseEvent, - mouseup: MouseEvent, - pause: Event, - play: Event, - playing: Event, - pointercancel: PointerEvent, - pointerdown: PointerEvent, - pointerenter: PointerEvent, - pointerleave: PointerEvent, - pointermove: PointerEvent, - pointerout: PointerEvent, - pointerover: PointerEvent, - pointerup: PointerEvent, - #[does_not_bubble] - progress: ProgressEvent, - ratechange: Event, - reset: Event, - resize: UiEvent, - #[does_not_bubble] - scroll: Event, - securitypolicyviolation: SecurityPolicyViolationEvent, - seeked: Event, - seeking: Event, - select: Event, - selectionchange: Event, - selectstart: Event, - graffchange: Event, - stalled: Event, - submit: SubmitEvent, - suspend: Event, - timeupdate: Event, - toggle: Event, - touchcancel: TouchEvent, - touchend: TouchEvent, - touchmove: TouchEvent, - touchstart: TouchEvent, - transitioncancel: TransitionEvent, - transitionend: TransitionEvent, - transitionrun: TransitionEvent, - transitionstart: TransitionEvent, - volumechange: Event, - waiting: Event, - webkitanimationend: Event, - webkitanimationiteration: Event, - webkitanimationstart: Event, - webkittransitionend: Event, - wheel: WheelEvent, - - // ========================================================= - // WindowEventMap - // ========================================================= - DOMContentLoaded: Event, - devicemotion: DeviceMotionEvent, - deviceorientation: DeviceOrientationEvent, - orientationchange: Event, - - // ========================================================= - // DocumentAndElementEventHandlersEventMap - // ========================================================= - copy: Event, // ClipboardEvent is unstable - cut: Event, // ClipboardEvent is unstable - paste: Event, // ClipboardEvent is unstable - - // ========================================================= - // DocumentEventMap - // ========================================================= - fullscreenchange: Event, - fullscreenerror: Event, - pointerlockchange: Event, - pointerlockerror: Event, - readystatechange: Event, - visibilitychange: Event, +/// Creates a custom event type, this is equal to [`Custom::new`]. +pub fn custom(name: impl Into>) -> Custom { + Custom::new(name) } diff --git a/crates/core/src/web/events/mod.rs b/crates/core/src/web/events/mod.rs index 9028212..93a901c 100644 --- a/crates/core/src/web/events/mod.rs +++ b/crates/core/src/web/events/mod.rs @@ -7,3 +7,196 @@ pub use csr::*; mod ssr; #[cfg(not(all(target_arch = "wasm32", feature = "web-csr")))] pub use ssr::*; + +use std::borrow::Cow; + +macro_rules! generate_event_types { + {$( + $( #[$does_not_bubble:ident] )? + $event:ident : $web_sys_event:ident + ),* $(,)?} => { + + $( + #[doc = concat!("The `", stringify!($event), "` event, which receives [", stringify!($web_sys_event), "](web_sys::", stringify!($web_sys_event), ") as its argument.")] + #[derive(Copy, Clone)] + #[allow(non_camel_case_types)] + pub struct $event; + + impl EventDescriptor for $event { + type EventType = web_sys::$web_sys_event; + + fn name(&self) -> Cow<'static, str> { + stringify!($event).into() + } + + $( + generate_event_types!($does_not_bubble); + )? + } + )* + }; + + (does_not_bubble) => { + fn bubbles(&self) -> bool { false } + } + } + +generate_event_types! { + // ========================================================= + // WindowEventHandlersEventMap + // ========================================================= + afterprint: Event, + beforeprint: Event, + beforeunload: BeforeUnloadEvent, + gamepadconnected: GamepadEvent, + gamepaddisconnected: GamepadEvent, + hashchange: HashChangeEvent, + languagechange: Event, + message: MessageEvent, + messageerror: MessageEvent, + offline: Event, + online: Event, + pagehide: PageTransitionEvent, + pageshow: PageTransitionEvent, + popstate: PopStateEvent, + rejectionhandled: PromiseRejectionEvent, + storage: StorageEvent, + unhandledrejection: PromiseRejectionEvent, + #[does_not_bubble] + unload: Event, + + // ========================================================= + // GlobalEventHandlersEventMap + // ========================================================= + #[does_not_bubble] + abort: UiEvent, + animationcancel: AnimationEvent, + animationend: AnimationEvent, + animationiteration: AnimationEvent, + animationstart: AnimationEvent, + auxclick: MouseEvent, + beforeinput: InputEvent, + #[does_not_bubble] + blur: FocusEvent, + canplay: Event, + canplaythrough: Event, + change: Event, + click: MouseEvent, + #[does_not_bubble] + close: Event, + compositionend: CompositionEvent, + compositionstart: CompositionEvent, + compositionupdate: CompositionEvent, + contextmenu: MouseEvent, + cuechange: Event, + dblclick: MouseEvent, + drag: DragEvent, + dragend: DragEvent, + dragenter: DragEvent, + dragleave: DragEvent, + dragover: DragEvent, + dragstart: DragEvent, + drop: DragEvent, + durationchange: Event, + emptied: Event, + ended: Event, + #[does_not_bubble] + error: ErrorEvent, + #[does_not_bubble] + focus: FocusEvent, + #[does_not_bubble] + focusin: FocusEvent, + #[does_not_bubble] + focusout: FocusEvent, + formdata: Event, // web_sys does not include `FormDataEvent` + gotpointercapture: PointerEvent, + input: Event, + invalid: Event, + keydown: KeyboardEvent, + keypress: KeyboardEvent, + keyup: KeyboardEvent, + #[does_not_bubble] + load: Event, + loadeddata: Event, + loadedmetadata: Event, + #[does_not_bubble] + loadstart: Event, + lostpointercapture: PointerEvent, + mousedown: MouseEvent, + mouseenter: MouseEvent, + mouseleave: MouseEvent, + mousemove: MouseEvent, + mouseout: MouseEvent, + mouseover: MouseEvent, + mouseup: MouseEvent, + pause: Event, + play: Event, + playing: Event, + pointercancel: PointerEvent, + pointerdown: PointerEvent, + pointerenter: PointerEvent, + pointerleave: PointerEvent, + pointermove: PointerEvent, + pointerout: PointerEvent, + pointerover: PointerEvent, + pointerup: PointerEvent, + #[does_not_bubble] + progress: ProgressEvent, + ratechange: Event, + reset: Event, + resize: UiEvent, + #[does_not_bubble] + scroll: Event, + securitypolicyviolation: SecurityPolicyViolationEvent, + seeked: Event, + seeking: Event, + select: Event, + selectionchange: Event, + selectstart: Event, + graffchange: Event, + stalled: Event, + submit: SubmitEvent, + suspend: Event, + timeupdate: Event, + toggle: Event, + touchcancel: TouchEvent, + touchend: TouchEvent, + touchmove: TouchEvent, + touchstart: TouchEvent, + transitioncancel: TransitionEvent, + transitionend: TransitionEvent, + transitionrun: TransitionEvent, + transitionstart: TransitionEvent, + volumechange: Event, + waiting: Event, + webkitanimationend: Event, + webkitanimationiteration: Event, + webkitanimationstart: Event, + webkittransitionend: Event, + wheel: WheelEvent, + + // ========================================================= + // WindowEventMap + // ========================================================= + DOMContentLoaded: Event, + devicemotion: DeviceMotionEvent, + deviceorientation: DeviceOrientationEvent, + orientationchange: Event, + + // ========================================================= + // DocumentAndElementEventHandlersEventMap + // ========================================================= + copy: Event, // ClipboardEvent is unstable + cut: Event, // ClipboardEvent is unstable + paste: Event, // ClipboardEvent is unstable + + // ========================================================= + // DocumentEventMap + // ========================================================= + fullscreenchange: Event, + fullscreenerror: Event, + pointerlockchange: Event, + pointerlockerror: Event, + readystatechange: Event, + visibilitychange: Event, +} diff --git a/crates/core/src/web/events/ssr.rs b/crates/core/src/web/events/ssr.rs index 92fc769..8532a99 100644 --- a/crates/core/src/web/events/ssr.rs +++ b/crates/core/src/web/events/ssr.rs @@ -75,193 +75,7 @@ impl Custom { } } -macro_rules! generate_event_types { - {$( - $( #[$does_not_bubble:ident] )? - $event:ident : $web_sys_event:ident - ),* $(,)?} => { - - $( - #[doc = concat!("The `", stringify!($event), "` event, which receives [", stringify!($web_sys_event), "](web_sys::", stringify!($web_sys_event), ") as its argument.")] - #[derive(Copy, Clone)] - #[allow(non_camel_case_types)] - pub struct $event; - - impl EventDescriptor for $event { - type EventType = web_sys::$web_sys_event; - - fn name(&self) -> Cow<'static, str> { - stringify!($event).into() - } - - $( - generate_event_types!($does_not_bubble); - )? - } - )* - }; - - (does_not_bubble) => { - fn bubbles(&self) -> bool { false } - } -} - -generate_event_types! { - // ========================================================= - // WindowEventHandlersEventMap - // ========================================================= - afterprint: Event, - beforeprint: Event, - beforeunload: BeforeUnloadEvent, - gamepadconnected: GamepadEvent, - gamepaddisconnected: GamepadEvent, - hashchange: HashChangeEvent, - languagechange: Event, - message: MessageEvent, - messageerror: MessageEvent, - offline: Event, - online: Event, - pagehide: PageTransitionEvent, - pageshow: PageTransitionEvent, - popstate: PopStateEvent, - rejectionhandled: PromiseRejectionEvent, - storage: StorageEvent, - unhandledrejection: PromiseRejectionEvent, - #[does_not_bubble] - unload: Event, - - // ========================================================= - // GlobalEventHandlersEventMap - // ========================================================= - #[does_not_bubble] - abort: UiEvent, - animationcancel: AnimationEvent, - animationend: AnimationEvent, - animationiteration: AnimationEvent, - animationstart: AnimationEvent, - auxclick: MouseEvent, - beforeinput: InputEvent, - #[does_not_bubble] - blur: FocusEvent, - canplay: Event, - canplaythrough: Event, - change: Event, - click: MouseEvent, - #[does_not_bubble] - close: Event, - compositionend: CompositionEvent, - compositionstart: CompositionEvent, - compositionupdate: CompositionEvent, - contextmenu: MouseEvent, - cuechange: Event, - dblclick: MouseEvent, - drag: DragEvent, - dragend: DragEvent, - dragenter: DragEvent, - dragleave: DragEvent, - dragover: DragEvent, - dragstart: DragEvent, - drop: DragEvent, - durationchange: Event, - emptied: Event, - ended: Event, - #[does_not_bubble] - error: ErrorEvent, - #[does_not_bubble] - focus: FocusEvent, - #[does_not_bubble] - focusin: FocusEvent, - #[does_not_bubble] - focusout: FocusEvent, - formdata: Event, // web_sys does not include `FormDataEvent` - gotpointercapture: PointerEvent, - input: Event, - invalid: Event, - keydown: KeyboardEvent, - keypress: KeyboardEvent, - keyup: KeyboardEvent, - #[does_not_bubble] - load: Event, - loadeddata: Event, - loadedmetadata: Event, - #[does_not_bubble] - loadstart: Event, - lostpointercapture: PointerEvent, - mousedown: MouseEvent, - mouseenter: MouseEvent, - mouseleave: MouseEvent, - mousemove: MouseEvent, - mouseout: MouseEvent, - mouseover: MouseEvent, - mouseup: MouseEvent, - pause: Event, - play: Event, - playing: Event, - pointercancel: PointerEvent, - pointerdown: PointerEvent, - pointerenter: PointerEvent, - pointerleave: PointerEvent, - pointermove: PointerEvent, - pointerout: PointerEvent, - pointerover: PointerEvent, - pointerup: PointerEvent, - #[does_not_bubble] - progress: ProgressEvent, - ratechange: Event, - reset: Event, - resize: UiEvent, - #[does_not_bubble] - scroll: Event, - securitypolicyviolation: SecurityPolicyViolationEvent, - seeked: Event, - seeking: Event, - select: Event, - selectionchange: Event, - selectstart: Event, - graffchange: Event, - stalled: Event, - submit: SubmitEvent, - suspend: Event, - timeupdate: Event, - toggle: Event, - touchcancel: TouchEvent, - touchend: TouchEvent, - touchmove: TouchEvent, - touchstart: TouchEvent, - transitioncancel: TransitionEvent, - transitionend: TransitionEvent, - transitionrun: TransitionEvent, - transitionstart: TransitionEvent, - volumechange: Event, - waiting: Event, - webkitanimationend: Event, - webkitanimationiteration: Event, - webkitanimationstart: Event, - webkittransitionend: Event, - wheel: WheelEvent, - - // ========================================================= - // WindowEventMap - // ========================================================= - DOMContentLoaded: Event, - devicemotion: DeviceMotionEvent, - deviceorientation: DeviceOrientationEvent, - orientationchange: Event, - - // ========================================================= - // DocumentAndElementEventHandlersEventMap - // ========================================================= - copy: Event, // ClipboardEvent is unstable - cut: Event, // ClipboardEvent is unstable - paste: Event, // ClipboardEvent is unstable - - // ========================================================= - // DocumentEventMap - // ========================================================= - fullscreenchange: Event, - fullscreenerror: Event, - pointerlockchange: Event, - pointerlockerror: Event, - readystatechange: Event, - visibilitychange: Event, +/// Creates a custom event type, this is equal to [`Custom::new`]. +pub fn custom(name: impl Into>) -> Custom { + Custom::new(name) } diff --git a/crates/routing/src/router.rs b/crates/routing/src/router.rs index fcc6855..b532764 100644 --- a/crates/routing/src/router.rs +++ b/crates/routing/src/router.rs @@ -1,4 +1,3 @@ -use std::cell::RefCell; use std::fmt::{self, Formatter}; use std::rc::Rc; diff --git a/examples/hackernews-salvo/.cargo/config.toml b/examples/hackernews-salvo/.cargo/config.toml new file mode 100644 index 0000000..feeb7c3 --- /dev/null +++ b/examples/hackernews-salvo/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target-dir = "target" # path of where to place all generated artifacts \ No newline at end of file diff --git a/examples/hackernews-salvo/Cargo.toml b/examples/hackernews-salvo/Cargo.toml index 772b75a..22397a0 100644 --- a/examples/hackernews-salvo/Cargo.toml +++ b/examples/hackernews-salvo/Cargo.toml @@ -14,7 +14,7 @@ serde = { version = "^1.0", features = ["derive"] } serde-aux = { version = "4", default-features = false } serde_json = { version = "1", optional = true } web-sys = { version = "0.3", features = ["Storage"] } -salvo = { version = "0.58", default-features = true, optional = true, features = ["serve-static"] } +salvo = { version = "0.60", default-features = true, optional = true, features = ["serve-static"] } tokio = { version = "1", optional = true } tracing = "0.1" tracing-subscriber = { version = "0.3", optional = true } diff --git a/examples/ssr-modes-salvo/Cargo.toml b/examples/ssr-modes-salvo/Cargo.toml index 8a9e9be..1326848 100644 --- a/examples/ssr-modes-salvo/Cargo.toml +++ b/examples/ssr-modes-salvo/Cargo.toml @@ -16,7 +16,7 @@ glory = { path = "../../crates/glory", default-features = false, features = ["ro serde = { version = "1", features = ["derive"] } serde_json = "1" web-sys = { version = "0.3", features = ["Storage"] } -salvo = { version = "0.58", default-features = true, optional = true, features = ["serve-static"] } +salvo = { version = "0.60", default-features = true, optional = true, features = ["serve-static"] } tokio = { version = "1", optional = true } tracing = "0.1" tracing-subscriber = "0.3" diff --git a/examples/ssr-simple-salvo/Cargo.toml b/examples/ssr-simple-salvo/Cargo.toml index d70b618..ca4c4e4 100644 --- a/examples/ssr-simple-salvo/Cargo.toml +++ b/examples/ssr-simple-salvo/Cargo.toml @@ -15,7 +15,7 @@ glory = { path = "../../crates/glory", default-features = false, features = ["ro serde = { version = "1", features = ["derive"] } serde_json = "1" web-sys = { version = "0.3", features = ["Storage"] } -salvo = { version = "0.58", default-features = true, optional = true, features = ["serve-static"] } +salvo = { version = "0.60", default-features = true, optional = true, features = ["serve-static"] } tokio = { version = "1", optional = true } tracing = "0.1" tracing-subscriber = { version = "0.3", optional = true }