diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 55bac8c4b..f0765e951 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,12 +12,15 @@ jobs: fail-fast: false matrix: include: - - target: x86_64-pc-windows-gnu - archive: zip + - target: x86_64-unknown-linux-gnu + archive: tar.gz tar.xz - target: x86_64-unknown-linux-musl archive: tar.gz tar.xz - target: x86_64-apple-darwin + archive: tar.gz tar.xz + - target: x86_64-pc-windows-gnu archive: zip + steps: - uses: actions/checkout@master - name: Compile and release diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 2ed974a47..858e42296 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -2,9 +2,10 @@ name: github pages on: push: + paths: + - docs/** branches: - main - pull_request: jobs: deploy: @@ -30,4 +31,4 @@ jobs: target-folder: docs/nightly/cli repository-name: dioxuslabs/docsite clean: false - token: ${{ secrets.DEPLOY_KEY }} # let's pretend I don't need it for now \ No newline at end of file + token: ${{ secrets.DEPLOY_KEY }} # let's pretend I don't need it for now diff --git a/Cargo.lock b/Cargo.lock index 75c5a10ff..58f5f7f2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,9 +49,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.61" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "508b352bb5c066aac251f6daf6b36eccd03e8a88e8081cd44959ea277a3af9a8" +checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" [[package]] name = "arrayref" @@ -233,9 +233,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "byteorder" @@ -456,9 +456,9 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "dc948ebb96241bb40ab73effeb80d9f93afaad49359d159a5e61be51619fe813" dependencies = [ "libc", ] @@ -542,40 +542,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "darling" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core", - "quote", - "syn", -] - [[package]] name = "data-encoding" version = "2.3.2" @@ -593,19 +559,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "dioxus" -version = "0.2.4" -source = "git+https://github.com/dioxuslabs/dioxus/#baf180733871848a178a5397a1e1934c768e04e8" -dependencies = [ - "dioxus-core", - "dioxus-core-macro", - "dioxus-hooks", - "dioxus-html", - "dioxus-rsx", - "dioxus-rsx-interpreter", -] - [[package]] name = "dioxus-cli" version = "0.1.5" @@ -621,8 +574,8 @@ dependencies = [ "colored 2.0.0", "convert_case", "ctrlc", - "dioxus", - "dioxus-rsx-interpreter", + "dioxus-core", + "dioxus-rsx", "dirs 4.0.0", "fern", "flate2", @@ -656,10 +609,11 @@ dependencies = [ [[package]] name = "dioxus-core" version = "0.2.1" -source = "git+https://github.com/dioxuslabs/dioxus/#baf180733871848a178a5397a1e1934c768e04e8" +source = "git+https://github.com/dioxuslabs/dioxus/#928b5358b2b56b8431be9b8f4aba8130fd45cb08" dependencies = [ "backtrace", "bumpalo", + "dyn-clone", "futures-channel", "futures-util", "fxhash", @@ -672,75 +626,18 @@ dependencies = [ "smallvec", ] -[[package]] -name = "dioxus-core-macro" -version = "0.2.1" -source = "git+https://github.com/dioxuslabs/dioxus/#baf180733871848a178a5397a1e1934c768e04e8" -dependencies = [ - "dioxus-rsx", - "dioxus-rsx-interpreter", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dioxus-hooks" -version = "0.2.1" -source = "git+https://github.com/dioxuslabs/dioxus/#baf180733871848a178a5397a1e1934c768e04e8" -dependencies = [ - "dioxus-core", - "futures-channel", - "log", -] - -[[package]] -name = "dioxus-html" -version = "0.2.1" -source = "git+https://github.com/dioxuslabs/dioxus/#baf180733871848a178a5397a1e1934c768e04e8" -dependencies = [ - "dioxus-core", - "enumset", - "euclid", - "keyboard-types", -] - [[package]] name = "dioxus-rsx" version = "0.0.0" -source = "git+https://github.com/dioxuslabs/dioxus/#baf180733871848a178a5397a1e1934c768e04e8" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dioxus-rsx-interpreter" -version = "0.1.0" -source = "git+https://github.com/dioxuslabs/dioxus/#baf180733871848a178a5397a1e1934c768e04e8" +source = "git+https://github.com/dioxuslabs/dioxus/#928b5358b2b56b8431be9b8f4aba8130fd45cb08" dependencies = [ "dioxus-core", - "dioxus-hooks", - "dioxus-html", - "dioxus-rsx", - "dioxus-ssr", - "lazy_static", "proc-macro2", "quote", "serde", - "serde_json", "syn", ] -[[package]] -name = "dioxus-ssr" -version = "0.2.1" -source = "git+https://github.com/dioxuslabs/dioxus/#baf180733871848a178a5397a1e1934c768e04e8" -dependencies = [ - "dioxus-core", -] - [[package]] name = "dirs" version = "1.0.5" @@ -772,6 +669,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "dyn-clone" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" + [[package]] name = "either" version = "1.8.0" @@ -805,36 +708,6 @@ dependencies = [ "syn", ] -[[package]] -name = "enumset" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4799cdb24d48f1f8a7a98d06b7fde65a85a2d1e42b25a889f5406aa1fbefe074" -dependencies = [ - "enumset_derive", -] - -[[package]] -name = "enumset_derive" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea83a3fbdc1d999ccfbcbee717eab36f8edf2d71693a23ce0d7cca19e085304c" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "euclid" -version = "0.22.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b52c2ef4a78da0ba68fbe1fd920627411096d2ac478f7f4c9f3a54ba6705bade" -dependencies = [ - "num-traits", -] - [[package]] name = "failure" version = "0.1.8" @@ -1082,9 +955,9 @@ checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" [[package]] name = "h2" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" dependencies = [ "bytes", "fnv", @@ -1286,9 +1159,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.44" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf7d67cf4a22adc5be66e75ebdf769b3f2ea032041437a7061f97a63dad4b" +checksum = "ad2bfd338099682614d3ee3fe0cd72e0b6a41ca6a87f6a74a3bd593c91650501" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1303,12 +1176,6 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.2.3" @@ -1430,17 +1297,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "keyboard-types" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7668b7cff6a51fe61cdde64cd27c8a220786f399501b57ebe36f7d8112fd68" -dependencies = [ - "bitflags", - "serde", - "unicode-segmentation", -] - [[package]] name = "kqueue" version = "1.0.6" @@ -1475,9 +1331,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.131" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "libz-sys" @@ -1749,9 +1605,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" [[package]] name = "opaque-debug" @@ -1864,9 +1720,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pest" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69486e2b8c2d2aeb9762db7b4e00b0331156393555cff467f4163ff06821eef8" +checksum = "4b0560d531d1febc25a3c9398a62a71256c0178f2e3443baedd9ad4bb8c9deb4" dependencies = [ "thiserror", "ucd-trie", @@ -1874,9 +1730,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13570633aff33c6d22ce47dd566b10a3b9122c2fe9d8e7501895905be532b91" +checksum = "905708f7f674518498c1f8d644481440f476d39ca6ecae83319bba7c6c12da91" dependencies = [ "pest", "pest_generator", @@ -1884,9 +1740,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c567e5702efdc79fb18859ea74c3eb36e14c43da7b8c1f098a4ed6514ec7a0" +checksum = "5803d8284a629cc999094ecd630f55e91b561a1d1ba75e233b00ae13b91a69ad" dependencies = [ "pest", "pest_meta", @@ -1897,9 +1753,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb32be5ee3bbdafa8c7a18b0a8a8d962b66cfa2ceee4037f49267a50ee821fe" +checksum = "1538eb784f07615c6d9a8ab061089c6c54a344c5b4301db51990ca1c241e8c04" dependencies = [ "once_cell", "pest", @@ -1908,18 +1764,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", @@ -2254,9 +2110,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -2286,18 +2142,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.143" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.143" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" dependencies = [ "proc-macro2", "quote", @@ -2306,9 +2162,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.83" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "itoa", "ryu", @@ -2392,9 +2248,9 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "10c98bba371b9b22a71a9414e420f92ddeb2369239af08200816169d5e2dd7aa" dependencies = [ "libc", "winapi", @@ -2530,9 +2386,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45" +checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b" dependencies = [ "itoa", "libc", @@ -3367,7 +3223,7 @@ dependencies = [ "hmac", "pbkdf2", "sha1", - "time 0.3.13", + "time 0.3.14", "zstd", ] diff --git a/Cargo.toml b/Cargo.toml index a76c3eb16..b18c90a9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,10 +52,10 @@ tar = "0.4.38" zip = "0.6.2" tower = "0.4.12" -syn = { version = "1.0" } +syn = { version = "1.0", features = ["full", "extra-traits"] } -dioxus = { git = "https://github.com/dioxuslabs/dioxus/", features = ["hot-reload"] } -dioxus-rsx-interpreter = { git = "https://github.com/dioxuslabs/dioxus/" } +dioxus-core = { git = "https://github.com/dioxuslabs/dioxus/", features = ["hot-reload"] } +dioxus-rsx = { git = "https://github.com/dioxuslabs/dioxus/", features = ["hot-reload"] } proc-macro2 = { version = "1.0", features = ["span-locations"] } lazy_static = "1.4.0" @@ -66,4 +66,5 @@ ctrlc = "3.2.3" [[bin]] path = "src/main.rs" + name = "dioxus" diff --git a/README.md b/README.md index f8515f390..0d4b29971 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,30 @@

📦✨ Dioxus CLI

-

Tooling to supercharge dioxus projects

+

Tooling to supercharge Dioxus projects

-dioxus-cli (inspired by wasm-pack and webpack) is a tool to help get dioxus projects off the ground. It handles all the build, development, bundling, and publishing to make web development simple. +`dioxus-cli` (inspired by wasm-pack and webpack) is a tool for getting Dioxus projects up and running. It handles all of the build, bundling, development and publishing to simplify web development. -## Installation +# Installation -```shell -# for stable -$ cargo install dioxus-cli -# for latest -$ cargo install --git https://github.com/DioxusLabs/cli -# for developing -$ cargo install --path . --debug +## Stable +``` +cargo install dioxus-cli +``` +## Latest +``` +cargo install --git https://github.com/DioxusLabs/cli +``` +## Developing +``` +cargo install --path . --debug ``` -Now, `dioxus` is in your path, you can use `dioxus --help` to get the help document. +Now that `dioxus` is in the path, use `dioxus --help` to see the help information. ``` dioxus 0.1.2 -Build, bundle, & ship your Dioxus app +Build, Bundle & Ship Dioxus Apps USAGE: dioxus [FLAGS] @@ -42,9 +46,13 @@ SUBCOMMANDS: ## Get Started -You can use the `dioxus create project_name` to init a dioxus project, its will be clone from the [dioxus-template](https://github.com/DioxusLabs/dioxus-template). +Use `dioxus create project_name` to initialize a new Dioxus project.
-or you can assign the template path: +It will be cloned from the [dioxus-template](https://github.com/DioxusLabs/dioxus-template) repository. + +
+ +Alternatively, you can specify the template path: ``` dioxus create hello --template gh:dioxuslabs/dioxus-template diff --git a/src/cli/mod.rs b/src/cli/mod.rs index fb947b71e..3eb242bf5 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -25,7 +25,7 @@ use std::{ process::{Command, Stdio}, }; -/// Build, bundle, & ship your Dioxus app. +/// Build, Bundle & Ship Dioxus Apps. #[derive(Parser)] #[clap(name = "dioxus", version)] pub struct Cli { diff --git a/src/cli/serve/mod.rs b/src/cli/serve/mod.rs index 93770b6ed..6619da53d 100644 --- a/src/cli/serve/mod.rs +++ b/src/cli/serve/mod.rs @@ -56,7 +56,7 @@ impl Serve { } return Ok(()); } else if platform != "web" { - return custom_error!("Unsoppurt platform target."); + return custom_error!("Unsupported platform target."); } // generate dev-index page diff --git a/src/hot_reload.rs b/src/hot_reload.rs index 84bb415ed..c26e6bca7 100644 --- a/src/hot_reload.rs +++ b/src/hot_reload.rs @@ -6,6 +6,7 @@ pub enum DiffResult { RsxChanged(Vec<(Macro, TokenStream)>), } +/// Find any rsx calls in the given file and return a list of all the rsx calls that have changed. pub fn find_rsx(new: &File, old: &File) -> DiffResult { let mut rsx_calls = Vec::new(); if new.items.len() != old.items.len() { diff --git a/src/server/hot_reload.rs b/src/server/hot_reload.rs index ae8d67e08..7b6a43951 100644 --- a/src/server/hot_reload.rs +++ b/src/server/hot_reload.rs @@ -2,14 +2,14 @@ use axum::{ extract::{ws::Message, Extension, TypedHeader, WebSocketUpgrade}, response::IntoResponse, }; -use dioxus_rsx_interpreter::SetRsxMessage; +use dioxus_core::{prelude::TemplateId, CodeLocation, OwnedCodeLocation, SetTemplateMsg}; +use dioxus_rsx::try_parse_template; use std::{path::PathBuf, sync::Arc}; use super::BuildManager; pub use crate::hot_reload::{find_rsx, DiffResult}; use crate::CrateConfig; -pub use dioxus_rsx_interpreter::{error::Error, CodeLocation, SetManyRsxMessage}; pub use proc_macro2::TokenStream; pub use std::collections::HashMap; pub use std::sync::Mutex; @@ -21,7 +21,7 @@ use syn::spanned::Spanned; use tokio::sync::broadcast; pub struct HotReloadState { - pub messages: broadcast::Sender, + pub messages: broadcast::Sender, pub build_manager: Arc, pub last_file_rebuild: Arc>, pub watcher_config: CrateConfig, @@ -91,10 +91,12 @@ pub async fn hot_reload_handler( } } let mut new_str = String::new(); - file.read_to_string(&mut new_str).expect("Unable to read file"); + file.read_to_string(&mut new_str) + .expect("Unable to read file"); if let Ok(new_file) = syn::parse_file(&new_str) { if let Ok(old_file) = syn::parse_file(&v) { - if let DiffResult::RsxChanged(changed) = find_rsx(&new_file, &old_file) { + if let DiffResult::RsxChanged(changed) = find_rsx(&new_file, &old_file) + { for (old, new) in changed.into_iter() { let hr = get_location( &state.watcher_config.crate_dir, @@ -116,72 +118,54 @@ pub async fn hot_reload_handler( if let Some(last) = lines.last_mut() { // if there is only one line the start index of last line will be the start of the rsx!, not the start of the line if start.line == end.line { - *last = - last.split_at(end.column - start.column).0; + *last = last.split_at(end.column - start.column).0; } else { *last = last.split_at(end.column).0; } } let rsx = lines.join("\n"); - messages.push(SetRsxMessage { - location: hr, - new_text: rsx, - }); + + let old_dyn_ctx = try_parse_template( + &format!("{}", old.tokens), + hr.to_owned(), + None, + ) + .map(|(_, old_dyn_ctx)| old_dyn_ctx); + if let Ok((template, _)) = + try_parse_template(&rsx, hr.to_owned(), old_dyn_ctx.ok()) + { + messages.push(SetTemplateMsg(TemplateId(hr), template)); + } } } } } } - log::info!("finished"); } - - let msg = SetManyRsxMessage(messages); - if socket - .send(Message::Text(serde_json::to_string(&msg).unwrap())) - .await - .is_err() - { - return; + for msg in messages { + if socket + .send(Message::Text(serde_json::to_string(&msg).unwrap())) + .await + .is_err() + { + return; + } } + log::info!("finished"); } let mut rx = state.messages.subscribe(); let hot_reload_handle = tokio::spawn(async move { loop { - let read_set_rsx = rx.recv(); - let read_err = socket.recv(); - tokio::select! { - err = read_err => { - if let Some(Ok(err)) = err { - if let Message::Text(err) = err { - let error: Error = serde_json::from_str(&err).unwrap(); - match error{ - Error::ParseError(parse_error) => { - log::error!("parse error:\n--> at {}:{}:{}\n\t{:?}", parse_error.location.file_path, parse_error.location.line, parse_error.location.column, parse_error.message); - }, - Error::RecompileRequiredError(_) => { - if let Err(err) = state.build_manager.rebuild(){ - log::error!("{}", err); - } - } - } - } - } else { - break; - } - }, - set_rsx = read_set_rsx => { - if let Ok(rsx) = set_rsx { - if socket - .send(Message::Text(serde_json::to_string(&rsx).unwrap())) - .await - .is_err() - { - break; - }; - } - } - }; + if let Ok(rsx) = rx.recv().await { + if socket + .send(Message::Text(serde_json::to_string(&rsx).unwrap())) + .await + .is_err() + { + break; + }; + } } }); @@ -192,10 +176,10 @@ pub async fn hot_reload_handler( pub fn get_location(crate_path: &Path, path: &Path, ts: TokenStream) -> CodeLocation { let span = ts.span().start(); let relative = path.strip_prefix(crate_path).unwrap(); - CodeLocation { + CodeLocation::Dynamic(Box::new(OwnedCodeLocation { file_path: relative.display().to_string(), crate_path: crate_path.display().to_string(), line: span.line as u32, column: span.column as u32 + 1, - } + })) } diff --git a/src/server/mod.rs b/src/server/mod.rs index 6ab38f16a..3e5f19e48 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -8,8 +8,9 @@ use axum::{ }; use cargo_metadata::diagnostic::Diagnostic; use colored::Colorize; -use dioxus_rsx_interpreter::SetRsxMessage; -use notify::Watcher; +use dioxus_core::{prelude::TemplateId, SetTemplateMsg}; +use dioxus_rsx::try_parse_template; +use notify::{RecommendedWatcher, Watcher}; use syn::spanned::Spanned; use std::{net::UdpSocket, path::PathBuf, process::Command, sync::Arc}; @@ -108,102 +109,124 @@ pub async fn startup_hot_reload(port: u16, config: CrateConfig) -> Result<()> { .unwrap_or_else(|| vec![PathBuf::from("src")]); let watcher_config = config.clone(); - let mut watcher = notify::recommended_watcher(move |evt: notify::Result| { - let config = watcher_config.clone(); - if chrono::Local::now().timestamp() > last_update_time { - // Give time for the change to take effect before reading the file - std::thread::sleep(std::time::Duration::from_millis(100)); - let mut updated = false; - if let Ok(evt) = evt { - let mut messages = Vec::new(); - let mut needs_rebuild = false; - for path in evt.paths.clone() { - if path.extension().map(|p| p.to_str()).flatten() != Some("rs") { - continue; - } - let mut file = File::open(path.clone()).unwrap(); - let mut src = String::new(); - file.read_to_string(&mut src).expect("Unable to read file"); - // find changes to the rsx in the file - if let Ok(syntax) = syn::parse_file(&src) { - let mut last_file_rebuild = last_file_rebuild.lock().unwrap(); - if let Some(old_str) = last_file_rebuild.map.get(&path) { - if let Ok(old) = syn::parse_file(&old_str) { - updated = true; - match find_rsx(&syntax, &old) { - DiffResult::CodeChanged => { - needs_rebuild = true; - last_file_rebuild.map.insert(path, src); - } - DiffResult::RsxChanged(changed) => { - log::info!("🪁 reloading rsx"); - for (old, new) in changed.into_iter() { - let hr = get_location( - &crate_dir, - &path.to_path_buf(), - old.to_token_stream(), - ); - // get the original source code to preserve whitespace - let span = new.span(); - let start = span.start(); - let end = span.end(); - let mut lines: Vec<_> = src - .lines() - .skip(start.line - 1) - .take(end.line - start.line + 1) - .collect(); - if let Some(first) = lines.first_mut() { - *first = first.split_at(start.column).1; - } - if let Some(last) = lines.last_mut() { - // if there is only one line the start index of last line will be the start of the rsx!, not the start of the line - if start.line == end.line { - *last = - last.split_at(end.column - start.column).0; + let watcher_config = config.clone(); + let mut watcher = RecommendedWatcher::new( + move |evt: notify::Result| { + let config = watcher_config.clone(); + if chrono::Local::now().timestamp() > last_update_time { + // Give time for the change to take effect before reading the file + std::thread::sleep(std::time::Duration::from_millis(100)); + let mut updated = false; + if let Ok(evt) = evt { + let mut messages = Vec::new(); + let mut needs_rebuild = false; + for path in evt.paths.clone() { + if path.extension().map(|p| p.to_str()).flatten() != Some("rs") { + continue; + } + let mut file = File::open(path.clone()).unwrap(); + let mut src = String::new(); + file.read_to_string(&mut src).expect("Unable to read file"); + // find changes to the rsx in the file + if let Ok(syntax) = syn::parse_file(&src) { + let mut last_file_rebuild = last_file_rebuild.lock().unwrap(); + if let Some(old_str) = last_file_rebuild.map.get(&path) { + if let Ok(old) = syn::parse_file(&old_str) { + updated = true; + match find_rsx(&syntax, &old) { + DiffResult::CodeChanged => { + needs_rebuild = true; + last_file_rebuild.map.insert(path, src); + } + DiffResult::RsxChanged(changed) => { + log::info!("🪁 reloading rsx"); + for (old, new) in changed.into_iter() { + let hr = get_location( + &crate_dir, + &path.to_path_buf(), + old.to_token_stream(), + ); + // get the original source code to preserve whitespace + let span = new.span(); + let start = span.start(); + let end = span.end(); + let mut lines: Vec<_> = src + .lines() + .skip(start.line - 1) + .take(end.line - start.line + 1) + .collect(); + if let Some(first) = lines.first_mut() { + *first = first.split_at(start.column).1; + } + if let Some(last) = lines.last_mut() { + // if there is only one line the start index of last line will be the start of the rsx!, not the start of the line + if start.line == end.line { + *last = last + .split_at(end.column - start.column) + .0; + } else { + *last = last.split_at(end.column).0; + } + } + let rsx = lines.join("\n"); + + let old_dyn_ctx = try_parse_template( + &format!("{}", old.tokens), + hr.to_owned(), + None, + ) + .map(|(_, old_dyn_ctx)| old_dyn_ctx); + if let Ok((template, _)) = try_parse_template( + &rsx, + hr.to_owned(), + old_dyn_ctx.ok(), + ) { + messages.push(SetTemplateMsg( + TemplateId(hr), + template, + )); } else { - *last = last.split_at(end.column).0; + needs_rebuild = true; } } - let rsx = lines.join("\n"); - messages.push(SetRsxMessage { - location: hr, - new_text: rsx, - }); } } } + } else { + // if this is a new file, rebuild the project + *last_file_rebuild = FileMap::new(crate_dir.clone()); } - } else { - // if this is a new file, rebuild the project - *last_file_rebuild = FileMap::new(crate_dir.clone()); } } - } - if needs_rebuild { - match build_manager.rebuild() { - Ok(res) => { - print_console_info( - port, - &config, - PrettierOptions { - changed: evt.paths, - warnings: res.warnings, - elapsed_time: res.elapsed_time, - }, - ); - } - Err(err) => { - log::error!("{}", err); + if needs_rebuild { + match build_manager.rebuild() { + Ok(res) => { + print_console_info( + port, + &config, + PrettierOptions { + changed: evt.paths, + warnings: res.warnings, + elapsed_time: res.elapsed_time, + }, + ); + } + Err(err) => { + log::error!("{}", err); + } } } + for msg in messages { + let _ = hot_reload_tx.send(msg); + } } if updated { last_update_time = chrono::Local::now().timestamp(); } } - last_update_time = chrono::Local::now().timestamp(); - } - }) + }, + notify::Config::default(), + ) .unwrap(); for sub_path in allow_watch_path { @@ -215,6 +238,7 @@ pub async fn startup_hot_reload(port: u16, config: CrateConfig) -> Result<()> { .unwrap(); } + // start serve dev-server at 0.0.0.0:8080 print_console_info( port, @@ -430,6 +454,7 @@ pub struct PrettierOptions { } fn print_console_info(port: u16, config: &CrateConfig, options: PrettierOptions) { + if let Ok(native_clearseq) = Command::new(if cfg!(target_os = "windows") { "cls" } else {