diff --git a/.gitignore b/.gitignore index 630f1fa..3021c73 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ storage/* build/* buildroot/pixie.tar.gz pixie-web/dist +.*.swp diff --git a/pixie-server/Cargo.lock b/pixie-server/Cargo.lock index 5bd3969..4fbfdef 100644 --- a/pixie-server/Cargo.lock +++ b/pixie-server/Cargo.lock @@ -411,6 +411,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.30" @@ -418,6 +433,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -426,6 +442,34 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.30" @@ -444,9 +488,13 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -902,6 +950,7 @@ dependencies = [ "bytes", "clap", "env_logger", + "futures", "hex", "hostfile", "http-body-util", @@ -918,6 +967,7 @@ dependencies = [ "serde_json", "serde_yaml", "tokio", + "tokio-stream", "tower-http", ] @@ -1263,6 +1313,18 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + [[package]] name = "tokio-tungstenite" version = "0.21.0" diff --git a/pixie-server/Cargo.toml b/pixie-server/Cargo.toml index d62930b..bb148de 100644 --- a/pixie-server/Cargo.toml +++ b/pixie-server/Cargo.toml @@ -18,7 +18,7 @@ postcard = { version = "1.0.8", default-features = false, features = ["alloc"] } serde = "1.0.193" serde_derive = "1.0.193" serde_yaml = "0.9" -tokio = { version = "1.34.0", features = ["macros", "fs", "rt-multi-thread"] } +tokio = { version = "1.34.0", features = ["macros", "fs", "rt-multi-thread", "sync"] } serde_json = "1.0.108" hostfile = "0.2.0" hex = "0.4.3" @@ -26,6 +26,8 @@ axum = { version = "0.7.2", features = ["ws"] } tower-http = { version = "0.5.0", features = ["fs", "compression-gzip", "auth", "trace"] } bytes = "1.5.0" http-body-util = "0.1.0" +futures = "0.3.30" +tokio-stream = { version = "0.1.16", features = ["sync"] } [dependencies.pixie-shared] path = "../pixie-shared" diff --git a/pixie-server/src/http.rs b/pixie-server/src/http.rs index 56b715e..8753af4 100644 --- a/pixie-server/src/http.rs +++ b/pixie-server/src/http.rs @@ -2,20 +2,19 @@ use std::{net::Ipv4Addr, sync::Arc}; use anyhow::Result; use axum::{ - extract::{ - self, - ws::{self, Message}, - Path, - }, + body::Body, + extract::{self, Path}, http::StatusCode, response::IntoResponse, routing::get, Router, }; +use futures::StreamExt; use macaddr::MacAddr6; -use pixie_shared::{HttpConfig, WsUpdate}; +use pixie_shared::{HttpConfig, StatusUpdate}; use tokio::net::TcpListener; +use tokio_stream::wrappers::WatchStream; use tower_http::{ compression::CompressionLayer, services::ServeDir, trace::TraceLayer, validate_request::ValidateRequestHeaderLayer, @@ -146,58 +145,26 @@ async fn gc(extract::State(state): extract::State>) -> String { "".to_owned() } -async fn ws( - extract::State(state): extract::State>, - ws: extract::ws::WebSocketUpgrade, -) -> axum::response::Response { - ws.on_upgrade(move |mut socket| async move { - let msg = WsUpdate::Config(state.config.clone()); - let msg = serde_json::to_string(&msg).unwrap(); - let msg = Message::Text(msg); - socket.send(msg).await.unwrap(); - - let msg = WsUpdate::HostMap(state.hostmap.clone()); - let msg = serde_json::to_string(&msg).unwrap(); - let msg = Message::Text(msg); - socket.send(msg).await.unwrap(); - - let mut units_rx = state.units.subscribe(); - units_rx.mark_changed(); - - let mut image_rx = state.image_stats.subscribe(); - image_rx.mark_changed(); - - 'main_loop: loop { - tokio::select! { - ret = units_rx.changed() => { - ret.unwrap(); - let msg = { - let units = units_rx.borrow_and_update(); - let msg = WsUpdate::Units(units.clone()); - let msg = serde_json::to_string(&msg).unwrap(); - ws::Message::Text(msg) - }; - socket.send(msg).await.unwrap(); - } - ret = image_rx.changed() => { - ret.unwrap(); - let msg = { - let image_stats = image_rx.borrow_and_update(); - let msg = WsUpdate::ImageStats(image_stats.clone()); - let msg = serde_json::to_string(&msg).unwrap(); - ws::Message::Text(msg) - }; - socket.send(msg).await.unwrap(); - } - packet = socket.recv() => { - let packet = packet.unwrap().unwrap(); - if let Message::Close(_) = packet { - break 'main_loop; - } - } - }; - } - }) +async fn status(extract::State(state): extract::State>) -> impl IntoResponse { + let initial_messages = vec![ + StatusUpdate::Config(state.config.clone()), + StatusUpdate::HostMap(state.hostmap.clone()), + ]; + let mut units_rx = state.units.subscribe(); + units_rx.mark_changed(); + let units_rx = WatchStream::new(units_rx); + + let mut image_rx = state.image_stats.subscribe(); + image_rx.mark_changed(); + let image_rx = WatchStream::new(image_rx); + + let messages = + futures::stream::iter(initial_messages.into_iter()).chain(futures::stream::select( + image_rx.map(|x| StatusUpdate::ImageStats(x)), + units_rx.map(|x| StatusUpdate::Units(x)), + )); + let lines = messages.map(|msg| serde_json::to_string(&msg).map(|x| x + "\n")); + Body::from_stream(lines) } pub async fn main(state: Arc) -> Result<()> { @@ -209,7 +176,7 @@ pub async fn main(state: Arc) -> Result<()> { let admin_path = state.storage_dir.join("admin"); let router = Router::new() - .route("/admin/ws", get(ws)) + .route("/admin/status", get(status)) .route("/admin/gc", get(gc)) .route("/admin/action/:unit/:action", get(action)) .route("/admin/image/:unit/:image", get(image)) @@ -217,7 +184,6 @@ pub async fn main(state: Arc) -> Result<()> { "/", ServeDir::new(&admin_path).append_index_html_on_directories(true), ) - .layer(CompressionLayer::new()) .layer(ValidateRequestHeaderLayer::basic("admin", password)) .layer(TraceLayer::new_for_http()) .with_state(state); diff --git a/pixie-shared/src/lib.rs b/pixie-shared/src/lib.rs index c609456..ddc7c3f 100644 --- a/pixie-shared/src/lib.rs +++ b/pixie-shared/src/lib.rs @@ -122,7 +122,7 @@ pub enum TcpRequest { #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg(feature = "std")] -pub enum WsUpdate { +pub enum StatusUpdate { Config(config::Config), HostMap(HashMap), Units(Vec), diff --git a/pixie-web/Cargo.lock b/pixie-web/Cargo.lock index 1767973..66ff5c7 100644 --- a/pixie-web/Cargo.lock +++ b/pixie-web/Cargo.lock @@ -4,68 +4,149 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] -name = "ahash" -version = "0.7.8" +name = "aho-corasick" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ - "getrandom", - "once_cell", - "version_check", + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", ] [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "attribute-derive" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "1f1ee502851995027b06f99f5ffbeffa1406b38d0b318a1ebfa469332c6cbafd" +dependencies = [ + "attribute-derive-macro", + "derive-where", + "manyhow", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "attribute-derive-macro" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3601467f634cfe36c4780ca9c75dea9a5b34529c1f2810676a337e7e0997f954" +dependencies = [ + "collection_literals", + "interpolator", + "manyhow", + "proc-macro-utils 0.8.0", + "proc-macro2", + "quote", + "quote-use", + "syn", +] [[package]] name = "autocfg" -version = "1.2.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "blake3" -version = "1.5.1" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" +checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" dependencies = [ "arrayref", "arrayvec", @@ -76,15 +157,36 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "by_address" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" + +[[package]] +name = "bytes" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" + +[[package]] +name = "camino" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" [[package]] name = "cc" -version = "1.0.90" +version = "1.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -92,11 +194,283 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "codee" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d3ad3122b0001c7f140cf4d605ef9a9e2c24d96ab0b4fb4347b76de2425f445" +dependencies = [ + "thiserror", +] + +[[package]] +name = "collection_literals" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271" + +[[package]] +name = "config" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7328b20597b53c2454f0b1919720c25c7339051c02b72b7e05409e00b14132be" +dependencies = [ + "convert_case", + "lazy_static", + "nom", + "pathdiff", + "serde", + "toml", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "const_format" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "constant_time_eq" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "default-struct-builder" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fa90da96b8fd491f5754d1f7a731f73921e3b7aa0ce333c821a0e43666ac14" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive-where" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "drain_filter_polyfill" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fast-srgb8" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] [[package]] name = "futures" @@ -154,7 +528,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] @@ -189,31 +563,34 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.28.1" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "gloo-net" -version = "0.1.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2899cb1a13be9020b010967adc6b2a8a343b6f1428b90238c9d53ca24decc6db" +checksum = "c06f627b1a58ca3d42b45d6104bf1e1a03799df472df00988b6ba21accc10580" dependencies = [ "futures-channel", "futures-core", "futures-sink", "gloo-utils", + "http", "js-sys", "pin-project", "serde", @@ -226,9 +603,9 @@ dependencies = [ [[package]] name = "gloo-timers" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" dependencies = [ "futures-channel", "futures-core", @@ -238,9 +615,9 @@ dependencies = [ [[package]] name = "gloo-utils" -version = "0.1.7" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" dependencies = [ "js-sys", "serde", @@ -249,11 +626,27 @@ dependencies = [ "web-sys", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hermit-abi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "html-escape" @@ -265,50 +658,389 @@ dependencies = [ ] [[package]] -name = "indexmap" -version = "1.9.3" +name = "http" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ - "autocfg", - "hashbrown", + "bytes", + "fnv", + "itoa", ] [[package]] -name = "ipnet" -version = "2.9.0" +name = "http-body" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "serde", + "bytes", + "http", ] [[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.69" +name = "http-body-util" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ - "wasm-bindgen", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", ] [[package]] -name = "libc" -version = "0.2.153" +name = "httparse" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] -name = "log" -version = "0.4.21" +name = "hyper" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icondata_ai" +version = "0.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bf3a9c196a6a169f790639ecc8fdd4396660b1d53b905230bf0b364776a56fc" +dependencies = [ + "icondata_core", +] + +[[package]] +name = "icondata_core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c97be924215abd5e630d84e95a47c710138a6559b4c55039f4f33aa897fa859" + +[[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.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "interpolator" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8" + +[[package]] +name = "inventory" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" + +[[package]] +name = "ipnet" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" +dependencies = [ + "serde", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "leptos" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cbb3237c274dadf00dcc27db96c52601b40375117178fb24a991cda073624f0" +dependencies = [ + "cfg-if", + "leptos_config", + "leptos_dom", + "leptos_macro", + "leptos_reactive", + "leptos_server", + "server_fn", + "tracing", + "typed-builder", + "typed-builder-macro", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "leptos-use" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8914bd0ff8ab5029521540a6e15292dcc05d0f1a791a3aa8cc31a94436bfb" +dependencies = [ + "cfg-if", + "codee", + "cookie", + "default-struct-builder", + "futures-util", + "gloo-timers", + "js-sys", + "lazy_static", + "leptos", + "paste", + "thiserror", + "unic-langid", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "leptos_config" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ed778611380ddea47568ac6ad6ec5158d39b5bd59e6c4dcd24efc15dc3dc0d" +dependencies = [ + "config", + "regex", + "serde", + "thiserror", + "typed-builder", +] + +[[package]] +name = "leptos_dom" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8401c46c86c1f4c16dcb7881ed319fcdca9cda9b9e78a6088955cb423afcf119" +dependencies = [ + "async-recursion", + "cfg-if", + "drain_filter_polyfill", + "futures", + "getrandom", + "html-escape", + "indexmap", + "itertools", + "js-sys", + "leptos_reactive", + "once_cell", + "pad-adapter", + "paste", + "rustc-hash", + "serde", + "serde_json", + "server_fn", + "smallvec", + "tracing", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "leptos_hot_reload" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb53d4794240b684a2f4be224b84bee9e62d2abc498cf2bcd643cd565e01d96" +dependencies = [ + "anyhow", + "camino", + "indexmap", + "parking_lot", + "proc-macro2", + "quote", + "rstml", + "serde", + "syn", + "walkdir", +] + +[[package]] +name = "leptos_macro" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b13bc3db70715cd8218c4535a5af3ae3c0e5fea6f018531fc339377b36bc0e0" +dependencies = [ + "attribute-derive", + "cfg-if", + "convert_case", + "html-escape", + "itertools", + "leptos_hot_reload", + "prettyplease", + "proc-macro-error2", + "proc-macro2", + "quote", + "rstml", + "server_fn_macro", + "syn", + "tracing", + "uuid", +] + +[[package]] +name = "leptos_reactive" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4161acbf80f59219d8d14182371f57302bc7ff81ee41aba8ba1ff7295727f23" +dependencies = [ + "base64", + "cfg-if", + "futures", + "indexmap", + "js-sys", + "oco_ref", + "paste", + "pin-project", + "rustc-hash", + "self_cell", + "serde", + "serde-wasm-bindgen", + "serde_json", + "slotmap", + "thiserror", + "tracing", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "leptos_server" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a97eb90a13f71500b831c7119ddd3bdd0d7ae0a6b0487cade4fddeed3b8c03f" +dependencies = [ + "inventory", + "lazy_static", + "leptos_macro", + "leptos_reactive", + "serde", + "server_fn", + "thiserror", + "tracing", +] + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "macaddr" @@ -319,30 +1051,112 @@ dependencies = [ "serde", ] +[[package]] +name = "manyhow" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91ea592d76c0b6471965708ccff7e6a5d277f676b90ab31f4d3f3fc77fade64" +dependencies = [ + "manyhow-macros", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "manyhow-macros" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64621e2c08f2576e4194ea8be11daf24ac01249a4f53cd8befcbb7077120ead" +dependencies = [ + "proc-macro-utils 0.8.0", + "proc-macro2", + "quote", +] + [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "adler", + "autocfg", ] [[package]] name = "object" -version = "0.32.2" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] +[[package]] +name = "oco_ref" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51ebcefb2f0b9a5e0bea115532c8ae4215d1b01eff176d0f4ba4192895c2708" +dependencies = [ + "serde", + "thiserror", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -350,304 +1164,983 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] -name = "paste" -version = "1.0.14" +name = "pad-adapter" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "56d80efc4b6721e8be2a10a5df21a30fa0b470f1539e53d8b4e6e75faf938b63" [[package]] -name = "pin-project" -version = "1.1.5" +name = "palette" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6" dependencies = [ - "pin-project-internal", + "approx", + "fast-srgb8", + "palette_derive", + "phf", +] + +[[package]] +name = "palette_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30" +dependencies = [ + "by_address", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pixie-shared" +version = "0.1.0" +dependencies = [ + "blake3", + "ipnet", + "macaddr", + "serde", +] + +[[package]] +name = "pixie-web" +version = "0.1.0" +dependencies = [ + "bytes", + "console_error_panic_hook", + "console_log", + "futures", + "leptos", + "leptos-use", + "log", + "pixie-shared", + "reqwest", + "serde_json", + "thaw", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "prettyplease" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-utils" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f59e109e2f795a5070e69578c4dc101068139f74616778025ae1011d4cd41a8" +dependencies = [ + "proc-macro2", + "quote", + "smallvec", +] + +[[package]] +name = "proc-macro-utils" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071" +dependencies = [ + "proc-macro2", + "quote", + "smallvec", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "version_check", + "yansi", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "quote-use" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9619db1197b497a36178cfc736dc96b271fe918875fbf1344c436a7e93d0321e" +dependencies = [ + "quote", + "quote-use-macros", +] + +[[package]] +name = "quote-use-macros" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82ebfb7faafadc06a7ab141a6f67bcfb24cb8beb158c6fe933f2f035afa99f35" +dependencies = [ + "proc-macro-utils 0.10.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "redox_syscall" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "reqwest" +version = "0.12.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" +dependencies = [ + "base64", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "windows-registry", +] + +[[package]] +name = "rstml" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe542870b8f59dd45ad11d382e5339c9a1047cde059be136a7016095bbdefa77" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", + "syn_derive", + "thiserror", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "self_cell" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" +dependencies = [ + "futures-core", +] + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_qs" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c" +dependencies = [ + "percent-encoding", + "serde", + "thiserror", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "server_fn" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fae7a3038a32e5a34ba32c6c45eb4852f8affaf8b794ebfcd4b1099e2d62ebe" +dependencies = [ + "bytes", + "ciborium", + "const_format", + "dashmap", + "futures", + "gloo-net", + "http", + "js-sys", + "once_cell", + "send_wrapper", + "serde", + "serde_json", + "serde_qs", + "server_fn_macro_default", + "thiserror", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "xxhash-rust", +] + +[[package]] +name = "server_fn_macro" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaaf648c6967aef78177c0610478abb5a3455811f401f3c62d10ae9bd3901a1" +dependencies = [ + "const_format", + "convert_case", + "proc-macro2", + "quote", + "syn", + "xxhash-rust", +] + +[[package]] +name = "server_fn_macro_default" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2aa8119b558a17992e0ac1fd07f080099564f24532858811ce04f742542440" +dependencies = [ + "server_fn_macro", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "serde", + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] -name = "pin-project-internal" -version = "1.1.5" +name = "syn_derive" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" dependencies = [ + "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.58", + "syn", ] [[package]] -name = "pin-project-lite" -version = "0.2.14" +name = "sync_wrapper" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] -name = "pin-utils" -version = "0.1.0" +name = "thaw" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "1a2ea14de27ddd0ce167c69e78852122c5a9c755b3c083c8249e491c4a8821ce" +dependencies = [ + "cfg-if", + "chrono", + "icondata_ai", + "icondata_core", + "leptos", + "num-traits", + "palette", + "thaw_components", + "thaw_utils", + "uuid", + "wasm-bindgen", + "web-sys", +] [[package]] -name = "pixie-shared" -version = "0.1.0" +name = "thaw_components" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4ee9d9598f7a5162845a83ef0ed3ccde52c23d987cf64433056b2fd4542161c" dependencies = [ - "blake3", - "ipnet", - "macaddr", - "serde", + "cfg-if", + "leptos", + "thaw_utils", + "uuid", + "web-sys", ] [[package]] -name = "pixie-web" -version = "0.1.0" +name = "thaw_utils" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5fe5c99ba6b6730ec533810dd4d92422b778d4fbaffa9b6d7fb705b28b3978" dependencies = [ - "futures", - "gloo-timers", - "macaddr", - "pixie-shared", - "reqwasm", - "serde", - "serde_json", - "sycamore", + "cfg-if", + "chrono", + "leptos", "wasm-bindgen", "web-sys", ] [[package]] -name = "proc-macro2" -version = "1.0.79" +name = "thiserror" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ - "unicode-ident", + "thiserror-impl", ] [[package]] -name = "quote" -version = "1.0.35" +name = "thiserror-impl" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", + "quote", + "syn", ] [[package]] -name = "reqwasm" -version = "0.5.0" +name = "time" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b89870d729c501fa7a68c43bf4d938bbb3a8c156d333d90faa0e8b3e3212fb" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ - "gloo-net", + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", ] [[package]] -name = "rustc-demangle" -version = "0.1.23" +name = "time-core" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] -name = "ryu" -version = "1.0.17" +name = "time-macros" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] [[package]] -name = "serde" -version = "1.0.197" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "serde_derive", + "displaydoc", ] [[package]] -name = "serde_derive" -version = "1.0.197" +name = "tinyvec" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "tinyvec_macros", ] [[package]] -name = "serde_json" -version = "1.0.115" +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ - "itoa", - "ryu", - "serde", + "backtrace", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.52.0", ] [[package]] -name = "slab" -version = "0.4.9" +name = "tokio-util" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ - "autocfg", + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", ] [[package]] -name = "slotmap" -version = "1.0.7" +name = "toml" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ - "version_check", + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", ] [[package]] -name = "smallvec" -version = "1.13.2" +name = "toml_datetime" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] [[package]] -name = "sycamore" -version = "0.8.2" +name = "toml_edit" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67817393b3c9828db84614f64db9a1ebb94729ce3a3751c41e7ff23d3f8e7f00" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "ahash", - "futures", "indexmap", - "js-sys", - "paste", - "sycamore-core", - "sycamore-futures", - "sycamore-macro", - "sycamore-reactive", - "sycamore-web", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] [[package]] -name = "sycamore-core" -version = "0.8.2" +name = "tower-service" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dce7f0440c5ea2b74a544deb5423708c023fade36e63515423d3f3ab5e1a998" -dependencies = [ - "ahash", - "sycamore-reactive", -] +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] -name = "sycamore-futures" -version = "0.8.0" +name = "tracing" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69e4f2b65a22059f711cb36adc454791248e9abdc0b6b04c5dda396098674f2" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "futures", - "sycamore-reactive", - "tokio", - "wasm-bindgen-futures", + "pin-project-lite", + "tracing-attributes", + "tracing-core", ] [[package]] -name = "sycamore-macro" -version = "0.8.2" +name = "tracing-attributes" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3abd3f402c1a943cf70860b91a40c79c713e269156445998dbfd647deac8a5" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] -name = "sycamore-reactive" -version = "0.8.1" +name = "tracing-core" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6376b578ad32f5f3ab6943bccec906fb0e1f0258a8bedf811afdec8c3330ef80" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ - "ahash", - "bumpalo", - "indexmap", - "slotmap", - "smallvec", + "once_cell", ] [[package]] -name = "sycamore-web" -version = "0.8.2" +name = "try-lock" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9520735f765e60718df8125eb27db19b990bed1116c9b3e8aae374dde1fe8" -dependencies = [ - "html-escape", - "indexmap", - "js-sys", - "once_cell", - "sycamore-core", - "sycamore-reactive", - "wasm-bindgen", - "web-sys", -] +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] -name = "syn" -version = "1.0.109" +name = "typed-builder" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "77739c880e00693faef3d65ea3aad725f196da38b22fdc7ea6ded6e1ce4d3add" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "typed-builder-macro", ] [[package]] -name = "syn" -version = "2.0.58" +name = "typed-builder-macro" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "1f718dfaf347dcb5b983bfc87608144b0bad87970aebcbea5ce44d2a30c08e63" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn", ] [[package]] -name = "thiserror" -version = "1.0.58" +name = "unic-langid" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "23dd9d1e72a73b25e07123a80776aae3e7b0ec461ef94f9151eed6ec88005a44" dependencies = [ - "thiserror-impl", + "unic-langid-impl", ] [[package]] -name = "thiserror-impl" -version = "1.0.58" +name = "unic-langid-impl" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "tinystr", ] [[package]] -name = "tokio" -version = "1.37.0" +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ - "backtrace", - "pin-project-lite", + "tinyvec", ] [[package]] -name = "unicode-ident" -version = "1.0.12" +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-xid" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "utf8-width" @@ -655,11 +2148,39 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom", +] + [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] [[package]] name = "wasi" @@ -669,36 +2190,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", - "serde", - "serde_json", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if", "js-sys", @@ -708,9 +2228,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -718,29 +2238,193 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "wasm-streams" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", ] + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "xxhash-rust" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984" + +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" diff --git a/pixie-web/Cargo.toml b/pixie-web/Cargo.toml index 7b9c698..ea483b2 100644 --- a/pixie-web/Cargo.toml +++ b/pixie-web/Cargo.toml @@ -4,13 +4,15 @@ version = "0.1.0" edition = "2021" [dependencies] -futures = "0.3.29" -gloo-timers = { version = "0.2.6", features = ["futures"] } -macaddr = "1.0.1" +bytes = "1.7.2" +console_error_panic_hook = "0.1.7" +console_log = "1.0.0" +futures = "0.3.30" +leptos = { version = "0.6.15", features = ["csr"] } +leptos-use = "0.13.5" +log = "0.4.22" +#macaddr = "1.0.1" pixie-shared = { version = "0.1.0", path = "../pixie-shared", features = ["macaddr", "std"] } -reqwasm = "0.5.0" -serde = "1.0.193" -serde_json = "1.0.108" -sycamore = { version = "0.8.2", features = ["sycamore-futures", "futures", "suspense"] } -wasm-bindgen = "0.2.89" -web-sys = { version = "0.3.66", features = ["Location"] } +reqwest = { version = "0.12.7", default-features = false, features = ["stream"] } +serde_json = "1.0.128" +thaw = { version = "0.3.4", features = ["csr"] } diff --git a/pixie-web/index.html b/pixie-web/index.html index dd6be67..3b3ec63 100644 --- a/pixie-web/index.html +++ b/pixie-web/index.html @@ -5,6 +5,7 @@ Pixie + diff --git a/pixie-web/src/main.rs b/pixie-web/src/main.rs index 445a508..1fde020 100644 --- a/pixie-web/src/main.rs +++ b/pixie-web/src/main.rs @@ -1,209 +1,32 @@ -use std::collections::HashMap; -use std::fmt; -use std::net::Ipv4Addr; -use std::ops::Deref; +use std::{collections::HashMap, fmt, net::Ipv4Addr}; use futures::StreamExt; -use gloo_timers::future::TimeoutFuture; -use pixie_shared::{Config, ImageStat, Unit, WsUpdate}; -use reqwasm::websocket::futures::WebSocket; -use reqwasm::websocket::Message; -use sycamore::futures::{spawn_local, spawn_local_scoped}; -use sycamore::prelude::*; -use wasm_bindgen::prelude::*; - -use reqwasm::http::Request; - -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(js_namespace = Date, js_name = now)] - fn date_now() -> f64; - - #[wasm_bindgen(js_namespace = console)] - fn log(s: &str); -} +use leptos::*; +use leptos_use::use_timestamp; +use pixie_shared::{Config, ImageStat, StatusUpdate, Unit}; +use reqwest::Url; +use thaw::{ + Button, ButtonColor, ButtonGroup, ButtonVariant, Popover, PopoverPlacement, PopoverTrigger, + Space, Table, Theme, ThemeProvider, +}; fn send_req(url: String) { + let url = if url.starts_with("http") { + Url::parse(&url).expect("invalid url") + } else { + let location = window().location(); + Url::parse(&location.href().expect("no href")) + .expect("invalid href") + .join(&url) + .expect("invalid url") + }; spawn_local(async move { - Request::get(&url) - .send() + reqwest::get(url.clone()) .await .unwrap_or_else(|_| panic!("Request to {} failed", url)); }); } -#[component(inline_props)] -fn UnitInfo(cx: Scope<'_>, unit: Unit, hostname: Option) -> View { - let time = create_signal::(cx, (date_now() * 0.001) as i64); - - spawn_local_scoped(cx, async move { - loop { - let now = date_now() as i64; - TimeoutFuture::new(1000 - (now % 1000) as u32).await; - time.set(now / 1000); - } - }); - - let ping_time = unit.last_ping_timestamp as i64; - let ping_ago = move || *time.get() - ping_time; - - let fmt_ca = move |unit: &Unit| { - if let Some(a) = unit.curr_action { - if let Some((x, y)) = unit.curr_progress { - format!("{} ({}/{})", a, x, y) - } else { - a.to_string() - } - } else { - format!( - "ping: {} seconds ago, {}", - ping_ago(), - String::from_utf8_lossy(&unit.last_ping_msg) - ) - } - }; - - let led_class = move || match ping_ago() { - ..=-1 => "led-blue", - 0..=119 => "led-green", - 120..=299 => "led-yellow", - 300.. => "led-red", - }; - - let mac = unit.mac.to_string(); - let mac_nocolon = mac.replace(':', ""); - - let id_pull = format!("machine-{mac_nocolon}-pull"); - let url_pull = format!("/admin/action/{mac}/pull"); - let id_push = format!("machine-{mac_nocolon}-push"); - let url_push = format!("/admin/action/{mac}/push"); - let id_boot = format!("machine-{mac_nocolon}-boot"); - let url_boot = format!("/admin/action/{mac}/reboot"); - let id_cancel = format!("machine-{mac_nocolon}-cancel"); - let url_cancel = format!("/admin/action/{mac}/wait"); - let id_register = format!("machine-{mac_nocolon}-register"); - let url_register = format!("/admin/action/{mac}/register"); - - let image = unit.image.clone(); - view! { cx, - tr { - td { - div(class=format!("{} tooltip", led_class())) { - span(class="tooltiptext") { (ping_ago()) " seconds ago" } - } - } - td { (hostname.clone().unwrap_or_default()) } - td { (unit.mac) } - td { (image) } - td { "row " (unit.row) " col " (unit.col) } - td { (unit.next_action) } - td { - button(id=id_pull, on:click=move |_| send_req(url_pull.clone()) ) { - "flash" - } - } - td { - button(id=id_push, on:click=move |_| send_req(url_push.clone()) ) { - "store" - } - } - td { - button(id=id_boot, on:click=move |_| send_req(url_boot.clone()) ) { - "reboot" - } - } - td { - button(id=id_cancel, on:click=move |_| send_req(url_cancel.clone()) ) { - "wait" - } - } - td { - button(id=id_register, on:click=move |_| send_req(url_register.clone()) ) { - "re-register" - } - } - td { (fmt_ca(&unit)) } - } - } -} - -#[component(inline_props)] -fn GroupInfo<'a, G: Html>( - cx: Scope<'a>, - units: Vec, - group_id: u8, - group_name: String, - images: Vec, - hostmap: HashMap, -) -> View { - let group_units = create_memo(cx, move || { - let mut units = units - .iter() - .filter(|x| x.group == group_id) - .cloned() - .collect::>(); - units.sort_by_key(|x| (x.row, x.col, x.mac)); - units - }); - - let id_pull = format!("group-{group_name}-pull"); - let url_pull = format!("/admin/action/{group_name}/pull"); - let id_boot = format!("group-{group_name}-boot"); - let url_boot = format!("/admin/action/{group_name}/reboot"); - let id_cancel = format!("group-{group_name}-cancel"); - let url_cancel = format!("/admin/action/{group_name}/wait"); - - let set_images = View::new_fragment( - images - .iter() - .map(|image| { - let url = format!("/admin/image/{group_name}/{image}"); - let text = format!("Set image to {:?}", image); - view! { cx, - button(on:click=move |_| send_req(url.clone())) { - (text) - } - } - }) - .collect(), - ); - - view! { cx, - h2 { (group_name) } - button(id=id_pull, on:click=move |_| send_req(url_pull.clone()) ) { - "Pull image on all machines" - } - button(id=id_boot, on:click=move |_| send_req(url_boot.clone()) ) { - "Set all machines to boot into the OS" - } - button(id=id_cancel, on:click=move |_| send_req(url_cancel.clone()) ) { - "Set all machines to wait for next command" - } - (set_images) - table { - tr { - th { } - th { "hostname" } - th { "mac" } - th { "image" } - th { "position" } - th { "next action" } - th(colspan=5) { "change action" } - th { "current action" } - } - Indexed( - iterable=group_units, - view=move |cx, x| { - let hostname = hostmap.get(&x.static_ip()).cloned(); - view! { cx, - UnitInfo(unit=x, hostname=hostname) - } - }, - ) - } - } -} - struct Bytes(u64); impl fmt::Display for Bytes { @@ -220,193 +43,328 @@ impl fmt::Display for Bytes { } } -#[component(inline_props)] -fn Images<'a, G: Html>(cx: Scope<'a>, images_signal: &'a ReadSignal>) -> View { - let make_image_row = move |name: String, image: (u64, u64)| { - let id_pull = format!("image-{name}-pull"); +#[component] +fn Images(#[prop(into)] images: Signal>) -> impl IntoView { + let image_row = move |(name, image): (String, (u64, u64))| { let url_pull = format!("/admin/action/{name}/pull"); - let id_boot = format!("image-{name}-boot"); let url_boot = format!("/admin/action/{name}/reboot"); - let id_cancel = format!("image-{name}-cancel"); let url_cancel = format!("/admin/action/{name}/wait"); - view! { cx, tr { - td { (name) } - td { (Bytes(image.0)) } - td { (Bytes(image.1)) } - td { - button(id=id_pull, on:click=move |_| send_req(url_pull.clone()) ) { - "Pull image on all machines" - } - } - td { - button(id=id_boot, on:click=move |_| send_req(url_boot.clone()) ) { - "Set all machines to boot into the OS" - } - } - td { - button(id=id_cancel, on:click=move |_| send_req(url_cancel.clone()) ) { - "Set all machines to wait for next command" - } - } - } + view! { + + {name} + {Bytes(image.0).to_string()} + {Bytes(image.1).to_string()} + + + + + + + + } }; - let images_table = move || { - View::new_fragment( - images_signal - .get() - .deref() - .as_ref() - .map(|images| { - images - .images - .iter() - .map(|(name, image)| make_image_row(name.clone(), *image)) - .collect() - }) - .unwrap_or_default(), - ) - }; - - let total_csize = move || { - images_signal - .get() - .deref() - .as_ref() - .map(|images| images.total_csize) - }; - - let reclaimable = move || { - images_signal - .get() - .deref() - .as_ref() - .map(|images| images.reclaimable) - }; - - view! { cx, - h1 { "Images" } - table { - tr { - th { "Image" } - th { "Size" } - th { "Compressed" } - } - (images_table()) - tr { - td { "Total" } - td { (Bytes(total_csize().unwrap_or_default())) } - } - tr { - td { "Reclaimable" } - td { (Bytes(reclaimable().unwrap_or_default())) } - td { } - td { - button(id="reclaime", on:click=move |_| send_req("/admin/gc".into()) ) { + let total_csize = move || images.get().as_ref().map(|images| images.total_csize); + + let reclaimable = move || images.get().as_ref().map(|images| images.reclaimable); + + view! { +

"Images"

+ + + + + + + + + + + + + + + + + + + +
"Image""Size""Compressed"
"Total"{move || Bytes(total_csize().unwrap_or_default()).to_string()}
"Reclaimable"{move || Bytes(reclaimable().unwrap_or_default()).to_string()} + +
+ } +} +#[component] +fn Group( + #[prop(into)] units: Signal>, + #[prop(into)] group_name: Signal, + images: Signal>, + hostmap: Signal>, + #[prop(into)] time: Signal, +) -> impl IntoView { + let render_unit = move |idx: usize| { + let unit = create_memo(move |_| units.get()[idx].clone()); + let ping_ago = move || time.get() - unit.get().last_ping_timestamp as i64; + + let mac = move || unit.get().mac.to_string(); + let url_pull = move || format!("/admin/action/{}/pull", mac()); + let url_push = move || format!("/admin/action/{}/push", mac()); + let url_boot = move || format!("/admin/action/{}/reboot", mac()); + let url_cancel = move || format!("/admin/action/{}/wait", mac()); + let url_register = move || format!("/admin/action/{}/register", mac()); + + let fmt_ca = move || { + let unit = unit.get(); + if let Some(a) = unit.curr_action { + if let Some((x, y)) = unit.curr_progress { + format!("{} ({}/{})", a, x, y) + } else { + a.to_string() } + } else { + format!( + "ping: {} seconds ago, {}", + ping_ago(), + String::from_utf8_lossy(&unit.last_ping_msg) + ) } + }; + + let led_class = move || match ping_ago() { + ..=-1 => "led-blue", + 0..=119 => "led-green", + 120..=299 => "led-yellow", + 300.. => "led-red", + }; + view! { + + + + +
+
+ {move || format!("{} seconds ago", ping_ago())} +
+ + + {move || { + hostmap.get().get(&unit.get().static_ip()).cloned().unwrap_or_default() + }} + + {move || unit.get().mac.to_string()} + {move || unit.get().image} + {move || format!("row {} col {}", unit.get().row, unit.get().col)} + {move || unit.get().next_action.to_string()} + + + + + + + + + + {fmt_ca} + } + .into_view() + }; + + let url_pull = move || format!("/admin/action/{}/pull", group_name.get()); + let url_boot = move || format!("/admin/action/{}/reboot", group_name.get()); + let url_cancel = move || format!("/admin/action/{}/wait", group_name.get()); + + let image_button = move |image: String| { + let text = format!("Set image to {:?}", image); + let url = move || format!("/admin/image/{}/{}", group_name.get(), image); + view! { + + } + }; + + view! { +

{group_name}

+ + + + + + + + + + + + + + + + + + + +
"hostname""mac""image""position""next action""change action""current action"
+
} } #[component] -async fn MainView(cx: Scope<'_>) -> View { - let config_signal = create_signal(cx, None::); - let hostmap_signal = create_signal(cx, None::>); - let units_signal = create_signal(cx, None::>); - let images_signal = create_signal(cx, None::); - - spawn_local_scoped(cx, async move { - let url = format!( - "ws://{}/admin/ws", - web_sys::window().unwrap().location().host().unwrap() - ); - - let mut ws = WebSocket::open(&url).unwrap_or_else(|err| { - log(&format!("Failed to open websocket: {:?}", err)); - panic!(); - }); +fn App() -> impl IntoView { + let (config, set_config) = create_signal(None::); + let (hostmap, set_hostname) = create_signal(None::>); + let (units, set_units) = create_signal(None::>); + let (image_stats, set_image_stats) = create_signal(None::); + + let images = Signal::derive(move || { + config + .get() + .map(|x| x.images.clone()) + .unwrap_or_else(Vec::new) + }); - loop { - let msg = ws - .next() - .await - .unwrap_or_else(|| { - log("Websocket closed"); - panic!(); - }) - .unwrap_or_else(|err| { - log(&format!("Websocket error: {:?}", err)); - panic!(); - }); + let location = + Url::parse(&window().location().href().expect("no href")).expect("invalid url href"); + let status_url = location + .join("admin/status") + .expect("could not make relative URL"); - match msg { - Message::Text(text) => { - let update: WsUpdate = serde_json::from_str(&text).unwrap_or_else(|err| { - log(&format!("Failed to parse websocket message: {:?}", err)); - panic!(); - }); + let handle_message = move |msg| match msg { + StatusUpdate::Units(u) => { + set_units.set(Some(u)); + } + StatusUpdate::Config(c) => { + set_config.set(Some(c)); + } + StatusUpdate::HostMap(h) => { + set_hostname.set(Some(h)); + } + StatusUpdate::ImageStats(i) => { + set_image_stats.set(Some(i)); + } + }; - match update { - WsUpdate::Config(config) => { - config_signal.set(Some(config)); - } - WsUpdate::HostMap(hostmap) => { - hostmap_signal.set(Some(hostmap)); - } - WsUpdate::Units(units) => { - units_signal.set(Some(units)); - } - WsUpdate::ImageStats(images) => { - images_signal.set(Some(images)); - } - } - } - Message::Bytes(_) => { - panic!("Unexpected binary message") + spawn_local(async move { + let stream = reqwest::get(status_url) + .await + .expect("could not connect to server"); + let mut buf = vec![]; + stream + .bytes_stream() + .for_each(|x| { + let data = x.unwrap(); + let mut data = &data[..]; + while let Some((newline_pos, _)) = + data.iter().enumerate().find(|(_, x)| **x == b'\n') + { + buf.extend_from_slice(&data[..newline_pos]); + let msg: StatusUpdate = + serde_json::from_slice(&buf).expect("invalid message from server"); + buf.clear(); + handle_message(msg); + data = &data[newline_pos + 1..]; } - } - } + buf.extend_from_slice(data); + + async {} + }) + .await; }); - let groups = move || { - let config_opt = config_signal.get().deref().clone(); - let units_opt = units_signal.get().deref().clone(); + let time = use_timestamp(); + let time_in_seconds = create_memo(move |_| (time.get() * 0.001) as i64); - View::new_fragment( - config_opt - .zip(units_opt) - .map(|(config, units)| { - config.groups - .iter() - .map(|(name, id)| { - let units = units.clone(); - let images = config.images.clone(); - let hostmap = hostmap_signal.get().deref().clone().unwrap_or_default(); - view! { cx, - GroupInfo(units=units, group_id=*id, group_name=name.clone(), images=images, hostmap=hostmap) } - }) - .collect() - }) - .unwrap_or_default() - ) + let render_group = move |id: u8| { + let group_name = create_memo(move |_| { + config + .get() + .unwrap() + .groups + .get_by_second(&id) + .unwrap() + .clone() + }); + let units = create_memo(move |_| -> Vec<_> { + units + .get() + .unwrap_or_else(Vec::new) + .iter() + .filter(|x| x.group == id) + .cloned() + .collect() + }); + let hostmap = Signal::derive(move || hostmap.get().unwrap_or_else(HashMap::new)); + view! { }.into_view() }; - view! { cx, - Images(images_signal=images_signal) - - h1 { "Groups" } - (groups()) + view! { + + } } fn main() { - sycamore::render(|cx| { - view! { cx, - MainView {} + console_error_panic_hook::set_once(); + console_log::init_with_level(log::Level::Debug).unwrap(); + + let theme: RwSignal = create_rw_signal(Theme::dark()); + + mount_to_body(move || { + view! { + + + } - }); + }) } diff --git a/pixie-web/style.css b/pixie-web/style.css index cc48e0d..d392b1d 100644 --- a/pixie-web/style.css +++ b/pixie-web/style.css @@ -30,34 +30,10 @@ box-shadow: inset #006 0 0 5px 1px; } -.tooltip { - position: relative; +.expand { + width: 100%; } -.tooltip .tooltiptext { - visibility: hidden; - width: 180px; - background-color: black; - color: #fff; - text-align: center; - border-radius: 6px; - padding: 5px 0; - position: absolute; - z-index: 1; - top: -8.25px; - left: 180%; -} -.tooltip:hover .tooltiptext { - visibility: visible; -} - -.tooltip .tooltiptext::after { - content: ""; - position: absolute; - top: 50%; - right: 100%; - margin-top: -5px; - border-width: 5px; - border-style: solid; - border-color: transparent black transparent transparent; +.thaw-button { + white-space: nowrap; }