From eec07583f16840f2c334c1c2f9b45688e105bb8f Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Mon, 18 Sep 2023 17:30:02 +0900 Subject: [PATCH 01/14] Agent v2 (#2773) * Make private bridges. * Add worker agent. * Add task type. * Memorised Task. * Add station. * Add Station Agent. * Subscription. * Station hooks. * Reactor Agents. * Add more description. * Restart station when closed. * Remove Station restart. * Send finish message to bridges. * Adds a method to read whether a bridge has received finish message for a subscription. * Update Reactor Agent. * Decouple macros from it. * Reactor Macro. * Reactivate Task. * Slightly adjust API. * Add documentation for reactor agents. * Remove Station. * Create Task macro. * Migrate Example. * Simplify Task Agent Design. * Implement Sink. * Agent -> Task in Example. * Switch to Registrable. * AgentScopeExt. * Finish AgentScopeExt. * Prelude. * Adjust prelude. * Fix imports. * Yew Agent. * Switch to upstreamed version of gloo. * Add stub reset. * Remove example. * Add Reset for Worker agents. * merge fix-ci into "agent-v2" * Switch to released version of gloo. * Adds Runtime. * A LocalRuntime. * Add note. * Add SSR benchmark. * Only create default runtime if no custom runtime is set. * Use jemalloc for benchmarking. * Remove once_cell for web assembly. * Add time. * Fix wasm_bindgen. * Adjust inlining. * merge local-runtime into "agent-v2" * Add reset. * Simplify task agent. * SSR for tasks. * Optimise benchmark output. * Optimise BufWriter. * Add json output. * Add Benchmark Workflow. * merge local-runtime into "agent-v2" * Makes Prepared States to be Rc'ed. * Move example. * Update example. * Implement prepared state for memorised tasks. * Make prepared states work on none runtime as well. * Finished prepared output. * Remove local set from tests. * Fix Workflow syntax. * Exclude benchmark from doc tests. * Tidy up the code. * Remove HashSet. * Fix rustfmt. * Some optimisation. * Use postcard. * Remove allocations. * Weak Ref. * Adjust feature flags. * Adds a pinned channel implementation. * Make Send bound explicit. * Migrate to pinned channel. * Implement on immutable reference. * Rename agent channel method. * Fix Sink close. * Fix closing. * Remove old platform. * Migrate to new macro. * Port Oneshot Agent. * Migrate reactor to gloo-worker. * Implement ScopeExt for Reactor. * Remove unneeded checks. * Update example note. * Fix doc tests. * Add an example for reactor agent. * Rename Prime to PrimeReactor. * Update Crate Information. * Remove unused dependencies. * Remove unused dependencies. * Update documentation. * Rename Bridge to Runner. * Update documentation. * Update documentation. * Update State name. * Merge outputs state for subscriptions. * Update documentation. * Fix doc link. * Make code link code link. * Make CODEC -> C. * Update Debug Implementation to type_name. * Fix readme. --- Cargo.lock | 163 +++++++++++- examples/README.md | 3 +- examples/web_worker_fib/Cargo.toml | 3 +- examples/web_worker_fib/README.md | 2 +- examples/web_worker_fib/index.html | 14 +- examples/web_worker_fib/src/agent.rs | 80 +++--- examples/web_worker_fib/src/bin/worker.rs | 6 +- examples/web_worker_fib/src/lib.rs | 122 +++++---- examples/web_worker_prime/Cargo.toml | 11 + examples/web_worker_prime/README.md | 17 ++ examples/web_worker_prime/index.html | 15 ++ examples/web_worker_prime/src/agent.rs | 38 +++ examples/web_worker_prime/src/bin/app.rs | 3 + examples/web_worker_prime/src/bin/worker.rs | 6 + examples/web_worker_prime/src/lib.rs | 64 +++++ packages/yew-agent-macro/Cargo.toml | 25 ++ packages/yew-agent-macro/src/agent_fn.rs | 241 +++++++++++++++++ packages/yew-agent-macro/src/lib.rs | 30 +++ packages/yew-agent-macro/src/oneshot.rs | 130 +++++++++ packages/yew-agent-macro/src/reactor.rs | 135 ++++++++++ packages/yew-agent/Cargo.toml | 7 +- packages/yew-agent/src/hooks.rs | 132 --------- packages/yew-agent/src/lib.rs | 111 +++++++- packages/yew-agent/src/oneshot/hooks.rs | 54 ++++ packages/yew-agent/src/oneshot/mod.rs | 12 + packages/yew-agent/src/oneshot/provider.rs | 130 +++++++++ packages/yew-agent/src/reach.rs | 8 + packages/yew-agent/src/reactor/hooks.rs | 280 ++++++++++++++++++++ packages/yew-agent/src/reactor/mod.rs | 53 ++++ packages/yew-agent/src/reactor/provider.rs | 133 ++++++++++ packages/yew-agent/src/scope_ext.rs | 145 ++++++++++ packages/yew-agent/src/utils.rs | 83 ++++++ packages/yew-agent/src/worker/hooks.rs | 219 +++++++++++++++ packages/yew-agent/src/worker/mod.rs | 77 ++++++ packages/yew-agent/src/worker/provider.rs | 159 +++++++++++ 35 files changed, 2442 insertions(+), 269 deletions(-) create mode 100644 examples/web_worker_prime/Cargo.toml create mode 100644 examples/web_worker_prime/README.md create mode 100644 examples/web_worker_prime/index.html create mode 100644 examples/web_worker_prime/src/agent.rs create mode 100644 examples/web_worker_prime/src/bin/app.rs create mode 100644 examples/web_worker_prime/src/bin/worker.rs create mode 100644 examples/web_worker_prime/src/lib.rs create mode 100644 packages/yew-agent-macro/Cargo.toml create mode 100644 packages/yew-agent-macro/src/agent_fn.rs create mode 100644 packages/yew-agent-macro/src/lib.rs create mode 100644 packages/yew-agent-macro/src/oneshot.rs create mode 100644 packages/yew-agent-macro/src/reactor.rs delete mode 100644 packages/yew-agent/src/hooks.rs create mode 100644 packages/yew-agent/src/oneshot/hooks.rs create mode 100644 packages/yew-agent/src/oneshot/mod.rs create mode 100644 packages/yew-agent/src/oneshot/provider.rs create mode 100644 packages/yew-agent/src/reach.rs create mode 100644 packages/yew-agent/src/reactor/hooks.rs create mode 100644 packages/yew-agent/src/reactor/mod.rs create mode 100644 packages/yew-agent/src/reactor/provider.rs create mode 100644 packages/yew-agent/src/scope_ext.rs create mode 100644 packages/yew-agent/src/utils.rs create mode 100644 packages/yew-agent/src/worker/hooks.rs create mode 100644 packages/yew-agent/src/worker/mod.rs create mode 100644 packages/yew-agent/src/worker/provider.rs diff --git a/Cargo.lock b/Cargo.lock index 9ab4d473a0e..3cfae99c917 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,6 +123,15 @@ dependencies = [ "yew", ] +[[package]] +name = "atomic-polyfill" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" +dependencies = [ + "critical-section", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -417,6 +426,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + [[package]] name = "colorchoice" version = "1.0.0" @@ -531,6 +546,12 @@ dependencies = [ "libc", ] +[[package]] +name = "critical-section" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" + [[package]] name = "crypto-common" version = "0.1.6" @@ -1149,9 +1170,9 @@ dependencies = [ [[package]] name = "gloo-worker" -version = "0.1.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09110b5555bcafe508cee0fb94308af9aac7a85f980d3c88b270d117c6c6911d" +checksum = "13471584da78061a28306d1359dd0178d8d6fc1c7c80e5e35d27260346e0516a" dependencies = [ "anymap2", "bincode", @@ -1159,28 +1180,42 @@ dependencies = [ "gloo-utils", "js-sys", "serde", - "slab", "wasm-bindgen", + "wasm-bindgen-futures", "web-sys", ] [[package]] name = "gloo-worker" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13471584da78061a28306d1359dd0178d8d6fc1c7c80e5e35d27260346e0516a" +checksum = "cdec38f5350e6f71425895382d3f0e5e45ad78b69c9905f097a171b80c73112c" dependencies = [ - "anymap2", "bincode", - "gloo-console", + "futures 0.3.28", "gloo-utils", + "gloo-worker-macros", "js-sys", + "pinned", "serde", + "thiserror", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", ] +[[package]] +name = "gloo-worker-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956caa58d4857bc9941749d55e4bd3000032d8212762586fa5705632967140e7" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.27", +] + [[package]] name = "h2" version = "0.3.20" @@ -1200,6 +1235,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1237,6 +1281,20 @@ dependencies = [ "http", ] +[[package]] +name = "heapless" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.4.1" @@ -2004,6 +2062,17 @@ dependencies = [ "yew", ] +[[package]] +name = "postcard" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9ee729232311d3cd113749948b689627618133b1c5012b77342c1950b25eaeb" +dependencies = [ + "cobs", + "heapless", + "serde", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2020,6 +2089,22 @@ dependencies = [ "syn 2.0.27", ] +[[package]] +name = "primes" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a61082d8bceecd71a3870e9162002bb75f7ba9c7aa8b76227e887782fef9c8" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -2452,6 +2537,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "ssr_router" @@ -2473,6 +2561,12 @@ dependencies = [ "yew", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "strsim" version = "0.10.0" @@ -2759,6 +2853,23 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" + +[[package]] +name = "toml_edit" +version = "0.19.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +dependencies = [ + "indexmap 2.0.0", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -3397,6 +3508,15 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "winnow" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acaaa1190073b2b101e15083c38ee8ec891b5e05cbee516521e94ec008f61e64" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.10.1" @@ -3438,9 +3558,24 @@ dependencies = [ name = "yew-agent" version = "0.2.0" dependencies = [ - "gloo-worker 0.1.2", + "futures 0.3.28", + "gloo-worker 0.3.0", "serde", + "wasm-bindgen", "yew", + "yew-agent-macro", +] + +[[package]] +name = "yew-agent-macro" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.27", + "trybuild", + "yew-agent", ] [[package]] @@ -3494,6 +3629,7 @@ name = "yew-worker-fib" version = "0.1.0" dependencies = [ "js-sys", + "postcard", "serde", "wasm-bindgen", "web-sys", @@ -3501,6 +3637,17 @@ dependencies = [ "yew-agent", ] +[[package]] +name = "yew-worker-prime" +version = "0.1.0" +dependencies = [ + "futures 0.3.28", + "primes", + "serde", + "yew", + "yew-agent", +] + [[package]] name = "zxcvbn" version = "2.2.2" diff --git a/examples/README.md b/examples/README.md index 58da019a898..1b5a01fa937 100644 --- a/examples/README.md +++ b/examples/README.md @@ -57,7 +57,8 @@ As an example, check out the TodoMVC example here: + - Yew • Web Worker Fibonacci + Yew • Web Worker Fibonacci + + + + - - - + + - - diff --git a/examples/web_worker_fib/src/agent.rs b/examples/web_worker_fib/src/agent.rs index e002caeada4..afe6f6803e5 100644 --- a/examples/web_worker_fib/src/agent.rs +++ b/examples/web_worker_fib/src/agent.rs @@ -1,59 +1,39 @@ +use js_sys::Uint8Array; use serde::{Deserialize, Serialize}; -use yew_agent::{HandlerId, Public, WorkerLink}; - -pub struct Worker { - link: WorkerLink, -} - -#[derive(Serialize, Deserialize)] -pub struct WorkerInput { - pub n: u32, -} - -#[derive(Serialize, Deserialize)] -pub struct WorkerOutput { - pub value: u32, -} - -impl yew_agent::Worker for Worker { - type Input = WorkerInput; - type Message = (); - type Output = WorkerOutput; - type Reach = Public; - - fn create(link: WorkerLink) -> Self { - Self { link } +use wasm_bindgen::JsValue; +use yew_agent::prelude::*; +use yew_agent::Codec; + +/// Example to use a custom codec. +pub struct Postcard; + +impl Codec for Postcard { + fn encode(input: I) -> JsValue + where + I: Serialize, + { + let buf = postcard::to_vec::<_, 32>(&input).expect("can't serialize a worker message"); + Uint8Array::from(buf.as_slice()).into() } - fn update(&mut self, _msg: Self::Message) { - // no messaging + fn decode(input: JsValue) -> O + where + O: for<'de> Deserialize<'de>, + { + let data = Uint8Array::from(input).to_vec(); + postcard::from_bytes(&data).expect("can't deserialize a worker message") } +} - fn handle_input(&mut self, msg: Self::Input, id: HandlerId) { - // this runs in a web worker - // and does not block the main - // browser thread! - - let n = msg.n; - - fn fib(n: u32) -> u32 { - if n <= 1 { - 1 - } else { - fib(n - 1) + fib(n - 2) - } +#[oneshot] +pub async fn FibonacciTask(n: u32) -> u32 { + fn fib(n: u32) -> u32 { + if n <= 1 { + 1 + } else { + fib(n - 1) + fib(n - 2) } - - let output = Self::Output { value: fib(n) }; - - self.link.respond(id, output); - } - - fn name_of_resource() -> &'static str { - "worker.js" } - fn resource_path_is_relative() -> bool { - true - } + fib(n) } diff --git a/examples/web_worker_fib/src/bin/worker.rs b/examples/web_worker_fib/src/bin/worker.rs index d785d8e067f..46bdb6f0dab 100644 --- a/examples/web_worker_fib/src/bin/worker.rs +++ b/examples/web_worker_fib/src/bin/worker.rs @@ -1,6 +1,6 @@ -use yew_agent::PublicWorker; -use yew_worker_fib::agent::Worker; +use yew_agent::Registrable; +use yew_worker_fib::agent::{FibonacciTask, Postcard}; fn main() { - Worker::register(); + FibonacciTask::registrar().encoding::().register(); } diff --git a/examples/web_worker_fib/src/lib.rs b/examples/web_worker_fib/src/lib.rs index 14813431551..5d072bf3e0e 100644 --- a/examples/web_worker_fib/src/lib.rs +++ b/examples/web_worker_fib/src/lib.rs @@ -3,82 +3,78 @@ pub mod agent; -use std::rc::Rc; - use web_sys::HtmlInputElement; +use yew::platform::spawn_local; use yew::prelude::*; -use yew_agent::{Bridge, Bridged}; +use yew_agent::oneshot::{use_oneshot_runner, OneshotProvider}; -use crate::agent::{Worker, WorkerInput, WorkerOutput}; +use crate::agent::{FibonacciTask, Postcard}; -pub struct App { - clicker_value: u32, - input_ref: NodeRef, - worker: Box>, - fibonacci_output: String, -} +#[function_component] +fn Main() -> Html { + let input_value = use_state_eq(|| 44); + let output = use_state(|| "Try out some fibonacci calculations!".to_string()); + let fib_task = use_oneshot_runner::(); -pub enum Message { - Click, - RunWorker, - WorkerMsg(WorkerOutput), -} + let clicker_value = use_state_eq(|| 0); -impl Component for App { - type Message = Message; - type Properties = (); + let calculate = { + let input_value = *input_value; + let output = output.clone(); + move |_e: MouseEvent| { + let fib_agent = fib_task.clone(); + let output = output.clone(); - fn create(ctx: &Context) -> Self { - let cb = { - let link = ctx.link().clone(); - move |e| link.send_message(Self::Message::WorkerMsg(e)) - }; - let worker = Worker::bridge(Rc::new(cb)); + spawn_local(async move { + // start the worker + let output_value = fib_agent.run(input_value).await; - Self { - clicker_value: 0, - input_ref: NodeRef::default(), - worker, - fibonacci_output: String::from("Try out some fibonacci calculations!"), + output.set(format!("Fibonacci value: {}", output_value)); + }); } - } + }; - fn update(&mut self, _ctx: &Context, msg: Self::Message) -> bool { - match msg { - Self::Message::Click => { - self.clicker_value += 1; - } - Self::Message::RunWorker => { - if let Some(input) = self.input_ref.cast::() { - // start the worker off! - self.worker.send(WorkerInput { - n: input.value_as_number() as u32, - }); - } - } - Self::Message::WorkerMsg(output) => { - // the worker is done! - self.fibonacci_output = format!("Fibonacci value: {}", output.value); - } + let on_input_change = { + let input_value = input_value.clone(); + move |e: InputEvent| { + input_value.set( + e.target_unchecked_into::() + .value() + .parse() + .expect("failed to parse"), + ); } + }; - true - } + let inc_clicker = { + let clicker_value = clicker_value.clone(); - fn view(&self, ctx: &Context) -> Html { - html! { - <> -

{ "Web worker demo" }

-

{ "Submit a value to calculate, then increase the counter on the main thread!"}

-

{ "Large numbers will take some time!" }

-

{ "Output: " } { &self.fibonacci_output }

-
- - -

-

{ "Main thread value: " } { self.clicker_value }

- - + move |_e: MouseEvent| { + clicker_value.set(*clicker_value + 1); } + }; + + html! { + <> +

{ "Web worker demo" }

+

{ "Submit a value to calculate, then increase the counter on the main thread!"}

+

{ "Large numbers will take some time!" }

+

{ "Output: " } { &*output }

+
+ + +

+

{ "Main thread value: " } { *clicker_value }

+ + + } +} + +#[function_component] +pub fn App() -> Html { + html! { + path="/worker.js"> +
+ > } } diff --git a/examples/web_worker_prime/Cargo.toml b/examples/web_worker_prime/Cargo.toml new file mode 100644 index 00000000000..b66142ba89b --- /dev/null +++ b/examples/web_worker_prime/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "yew-worker-prime" +version = "0.1.0" +edition = "2021" + +[dependencies] +yew-agent = { path = "../../packages/yew-agent" } +yew = { path = "../../packages/yew", features = ["csr"] } +futures = "0.3.25" +primes = "0.3.0" +serde = { version = "1.0.147", features = ["derive"] } diff --git a/examples/web_worker_prime/README.md b/examples/web_worker_prime/README.md new file mode 100644 index 00000000000..82ded23b81a --- /dev/null +++ b/examples/web_worker_prime/README.md @@ -0,0 +1,17 @@ +# Web Worker Prime + +[![Demo](https://img.shields.io/website?label=demo&url=https%3A%2F%2Fexamples.yew.rs%2Fweb_worker_prime)](https://examples.yew.rs/web_worker_prime) + +Calculate primes until stop button is pressed, without blocking the main thread. + +## Concepts + +The example illustrates how to use reactor agents to offload CPU bound tasks to a worker thread in a Yew application. + +## Running + +Run this application with the trunk development server: + +```bash +trunk serve --open +``` diff --git a/examples/web_worker_prime/index.html b/examples/web_worker_prime/index.html new file mode 100644 index 00000000000..eacef73d53d --- /dev/null +++ b/examples/web_worker_prime/index.html @@ -0,0 +1,15 @@ + + + + + + Yew • Web Worker Prime + + + + + + + + + diff --git a/examples/web_worker_prime/src/agent.rs b/examples/web_worker_prime/src/agent.rs new file mode 100644 index 00000000000..595239f1626 --- /dev/null +++ b/examples/web_worker_prime/src/agent.rs @@ -0,0 +1,38 @@ +use std::time::Duration; + +use futures::sink::SinkExt; +use futures::{FutureExt, StreamExt}; +use serde::{Deserialize, Serialize}; +use yew::platform::time::sleep; +use yew_agent::prelude::*; + +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum ControlSignal { + Start, + Stop, +} + +#[reactor] +pub async fn PrimeReactor(mut scope: ReactorScope) { + while let Some(m) = scope.next().await { + if m == ControlSignal::Start { + 'inner: for i in 1.. { + // This is not the most efficient way to calculate prime, + // but this example is here to demonstrate how primes can be + // sent to the application in an ascending order. + if primes::is_prime(i) { + scope.send(i).await.unwrap(); + } + + futures::select! { + m = scope.next() => { + if m == Some(ControlSignal::Stop) { + break 'inner; + } + }, + _ = sleep(Duration::from_millis(100)).fuse() => {}, + } + } + } + } +} diff --git a/examples/web_worker_prime/src/bin/app.rs b/examples/web_worker_prime/src/bin/app.rs new file mode 100644 index 00000000000..415969eb135 --- /dev/null +++ b/examples/web_worker_prime/src/bin/app.rs @@ -0,0 +1,3 @@ +fn main() { + yew::Renderer::::new().render(); +} diff --git a/examples/web_worker_prime/src/bin/worker.rs b/examples/web_worker_prime/src/bin/worker.rs new file mode 100644 index 00000000000..51b124e440f --- /dev/null +++ b/examples/web_worker_prime/src/bin/worker.rs @@ -0,0 +1,6 @@ +use yew_agent::Registrable; +use yew_worker_prime::agent::PrimeReactor; + +fn main() { + PrimeReactor::registrar().register(); +} diff --git a/examples/web_worker_prime/src/lib.rs b/examples/web_worker_prime/src/lib.rs new file mode 100644 index 00000000000..a909f90f2e0 --- /dev/null +++ b/examples/web_worker_prime/src/lib.rs @@ -0,0 +1,64 @@ +pub mod agent; +use agent::{ControlSignal, PrimeReactor}; +use yew::prelude::*; +use yew_agent::reactor::{use_reactor_subscription, ReactorProvider}; + +#[function_component] +fn Main() -> Html { + let prime_sub = use_reactor_subscription::(); + let started = use_state_eq(|| false); + let skip_len = use_state_eq(|| 0); + + let result_s = prime_sub + .iter() + // Skip results in previous runs. + .skip(*skip_len) + .fold("".to_string(), |mut output, item| { + if !output.is_empty() { + output.push_str(", "); + } + + output.push_str(&item.to_string()); + + output + }); + + let start_prime_calc = use_callback( + (prime_sub.clone(), started.setter(), skip_len.setter()), + |_input, (prime_sub, started_setter, skip_len)| { + skip_len.set(prime_sub.len()); + prime_sub.send(ControlSignal::Start); + started_setter.set(true); + }, + ); + + let stop_prime_calc = use_callback( + (prime_sub, started.setter()), + |_input, (prime_sub, started_setter)| { + prime_sub.send(ControlSignal::Stop); + started_setter.set(false); + }, + ); + + html! { + <> +

{"Find Prime"}

+

{"This page demonstrates how to calculate prime in a web worker."}

+ if *started { + + } else { + + } +
{result_s}
+ + } +} + +#[function_component] +pub fn App() -> Html { + html! { + path="/worker.js"> +
+ > + } +} diff --git a/packages/yew-agent-macro/Cargo.toml b/packages/yew-agent-macro/Cargo.toml new file mode 100644 index 00000000000..69548444adf --- /dev/null +++ b/packages/yew-agent-macro/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "yew-agent-macro" +version = "0.1.0" +edition = "2021" +rust-version = "1.64.0" +authors = ["Kaede Hoshikawa "] +repository = "https://github.com/yewstack/yew" +homepage = "https://yew.rs" +documentation = "https://docs.rs/yew/" +readme = "../../README.md" +description = "Macro Support for Yew Agents" +license = "MIT OR Apache-2.0" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1" +quote = "1" +syn = { version = "2", features = ["full", "extra-traits"] } + +[dev-dependencies] +rustversion = "1" +trybuild = "1" +yew-agent = { path = "../yew-agent" } diff --git a/packages/yew-agent-macro/src/agent_fn.rs b/packages/yew-agent-macro/src/agent_fn.rs new file mode 100644 index 00000000000..ef598323bd1 --- /dev/null +++ b/packages/yew-agent-macro/src/agent_fn.rs @@ -0,0 +1,241 @@ +use proc_macro2::{Span, TokenStream}; +use quote::ToTokens; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::token::Comma; +use syn::{Attribute, FnArg, Generics, Ident, Item, ItemFn, Signature, Type, Visibility}; + +pub trait AgentFnType { + type RecvType; + type OutputType; + + fn attr_name() -> &'static str; + fn agent_type_name() -> &'static str; + fn parse_recv_type(sig: &Signature) -> syn::Result; + fn parse_output_type(sig: &Signature) -> syn::Result; + + fn extract_fn_arg_type(arg: &FnArg) -> syn::Result { + let ty = match arg { + FnArg::Typed(arg) => arg.ty.clone(), + + FnArg::Receiver(_) => { + return Err(syn::Error::new_spanned( + arg, + format!("{} agents can't accept a receiver", Self::agent_type_name()), + )); + } + }; + + Ok(*ty) + } + + fn assert_no_left_argument(rest_inputs: I, expected_len: usize) -> syn::Result<()> + where + I: ExactSizeIterator + IntoIterator, + T: ToTokens, + { + // Checking after param parsing may make it a little inefficient + // but that's a requirement for better error messages in case of receivers + // `>0` because first one is already consumed. + if rest_inputs.len() > 0 { + let params: TokenStream = rest_inputs + .into_iter() + .map(|it| it.to_token_stream()) + .collect(); + return Err(syn::Error::new_spanned( + params, + format!( + "{} agent can accept at most {} argument{}", + Self::agent_type_name(), + expected_len, + if expected_len > 1 { "s" } else { "" } + ), + )); + } + + Ok(()) + } +} + +#[derive(Clone)] +pub struct AgentFn +where + F: AgentFnType + 'static, +{ + pub recv_type: F::RecvType, + pub output_type: F::OutputType, + pub generics: Generics, + pub vis: Visibility, + pub attrs: Vec, + pub name: Ident, + pub agent_name: Option, + pub is_async: bool, + + pub func: ItemFn, +} + +impl Parse for AgentFn +where + F: AgentFnType + 'static, +{ + fn parse(input: ParseStream) -> syn::Result { + let parsed: Item = input.parse()?; + + let func = match parsed { + Item::Fn(m) => m, + + item => { + return Err(syn::Error::new_spanned( + item, + format!( + "`{}` attribute can only be applied to functions", + F::attr_name() + ), + )) + } + }; + + let ItemFn { + attrs, vis, sig, .. + } = func.clone(); + + if sig.generics.lifetimes().next().is_some() { + return Err(syn::Error::new_spanned( + sig.generics, + format!( + "{} agents can't have generic lifetime parameters", + F::agent_type_name() + ), + )); + } + + if sig.constness.is_some() { + return Err(syn::Error::new_spanned( + sig.constness, + format!("const functions can't be {} agents", F::agent_type_name()), + )); + } + + if sig.abi.is_some() { + return Err(syn::Error::new_spanned( + sig.abi, + format!("extern functions can't be {} agents", F::agent_type_name()), + )); + } + let recv_type = F::parse_recv_type(&sig)?; + let output_type = F::parse_output_type(&sig)?; + + let is_async = sig.asyncness.is_some(); + + Ok(Self { + recv_type, + output_type, + generics: sig.generics, + is_async, + vis, + attrs, + name: sig.ident, + agent_name: None, + func, + }) + } +} + +impl AgentFn +where + F: AgentFnType + 'static, +{ + /// Filters attributes that should be copied to agent definition. + pub fn filter_attrs_for_agent_struct(&self) -> Vec { + self.attrs + .iter() + .filter_map(|m| { + m.path() + .get_ident() + .and_then(|ident| match ident.to_string().as_str() { + "doc" | "allow" => Some(m.clone()), + _ => None, + }) + }) + .collect() + } + + /// Filters attributes that should be copied to the agent impl block. + pub fn filter_attrs_for_agent_impl(&self) -> Vec { + self.attrs + .iter() + .filter_map(|m| { + m.path() + .get_ident() + .and_then(|ident| match ident.to_string().as_str() { + "allow" => Some(m.clone()), + _ => None, + }) + }) + .collect() + } + + pub fn phantom_generics(&self) -> Punctuated { + self.generics + .type_params() + .map(|ty_param| ty_param.ident.clone()) // create a new Punctuated sequence without any type bounds + .collect::>() + } + + pub fn merge_agent_name(&mut self, name: AgentName) -> syn::Result<()> { + if let Some(ref m) = name.agent_name { + if m == &self.name { + return Err(syn::Error::new_spanned( + m, + format!( + "the {} must not have the same name as the function", + F::agent_type_name() + ), + )); + } + } + + self.agent_name = name.agent_name; + + Ok(()) + } + + pub fn inner_fn_ident(&self) -> Ident { + if self.agent_name.is_some() { + self.name.clone() + } else { + Ident::new("inner", Span::mixed_site()) + } + } + + pub fn agent_name(&self) -> Ident { + self.agent_name.clone().unwrap_or_else(|| self.name.clone()) + } + + pub fn print_inner_fn(&self) -> ItemFn { + let mut func = self.func.clone(); + func.sig.ident = self.inner_fn_ident(); + + func.vis = Visibility::Inherited; + + func + } +} + +pub struct AgentName { + agent_name: Option, +} + +impl Parse for AgentName { + fn parse(input: ParseStream) -> syn::Result { + if input.is_empty() { + return Ok(Self { agent_name: None }); + } + + let agent_name = input.parse()?; + + Ok(Self { + agent_name: Some(agent_name), + }) + } +} diff --git a/packages/yew-agent-macro/src/lib.rs b/packages/yew-agent-macro/src/lib.rs new file mode 100644 index 00000000000..8acd9797357 --- /dev/null +++ b/packages/yew-agent-macro/src/lib.rs @@ -0,0 +1,30 @@ +use proc_macro::TokenStream; +use syn::parse_macro_input; + +mod agent_fn; +mod oneshot; +mod reactor; + +use agent_fn::{AgentFn, AgentName}; +use oneshot::{oneshot_impl, OneshotFn}; +use reactor::{reactor_impl, ReactorFn}; + +#[proc_macro_attribute] +pub fn reactor(attr: TokenStream, item: TokenStream) -> TokenStream { + let item = parse_macro_input!(item as AgentFn); + let attr = parse_macro_input!(attr as AgentName); + + reactor_impl(attr, item) + .unwrap_or_else(|err| err.to_compile_error()) + .into() +} + +#[proc_macro_attribute] +pub fn oneshot(attr: TokenStream, item: TokenStream) -> TokenStream { + let item = parse_macro_input!(item as AgentFn); + let attr = parse_macro_input!(attr as AgentName); + + oneshot_impl(attr, item) + .unwrap_or_else(|err| err.to_compile_error()) + .into() +} diff --git a/packages/yew-agent-macro/src/oneshot.rs b/packages/yew-agent-macro/src/oneshot.rs new file mode 100644 index 00000000000..0d22ef2558c --- /dev/null +++ b/packages/yew-agent-macro/src/oneshot.rs @@ -0,0 +1,130 @@ +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::{parse_quote, Ident, ReturnType, Signature, Type}; + +use crate::agent_fn::{AgentFn, AgentFnType, AgentName}; + +pub struct OneshotFn {} + +impl AgentFnType for OneshotFn { + type OutputType = Type; + type RecvType = Type; + + fn attr_name() -> &'static str { + "oneshot" + } + + fn agent_type_name() -> &'static str { + "oneshot" + } + + fn parse_recv_type(sig: &Signature) -> syn::Result { + let mut inputs = sig.inputs.iter(); + let arg = inputs + .next() + .ok_or_else(|| syn::Error::new_spanned(&sig.ident, "expected 1 argument"))?; + + let ty = Self::extract_fn_arg_type(arg)?; + + Self::assert_no_left_argument(inputs, 1)?; + + Ok(ty) + } + + fn parse_output_type(sig: &Signature) -> syn::Result { + let ty = match &sig.output { + ReturnType::Default => { + parse_quote! { () } + } + ReturnType::Type(_, ty) => *ty.clone(), + }; + + Ok(ty) + } +} + +pub fn oneshot_impl(name: AgentName, mut agent_fn: AgentFn) -> syn::Result { + agent_fn.merge_agent_name(name)?; + + let struct_attrs = agent_fn.filter_attrs_for_agent_struct(); + let oneshot_impl_attrs = agent_fn.filter_attrs_for_agent_impl(); + let phantom_generics = agent_fn.phantom_generics(); + let oneshot_name = agent_fn.agent_name(); + let fn_name = agent_fn.inner_fn_ident(); + let inner_fn = agent_fn.print_inner_fn(); + + let AgentFn { + recv_type: input_type, + generics, + output_type, + vis, + is_async, + .. + } = agent_fn; + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let fn_generics = ty_generics.as_turbofish(); + + let in_ident = Ident::new("_input", Span::mixed_site()); + + let fn_call = if is_async { + quote! { #fn_name #fn_generics (#in_ident).await } + } else { + quote! { #fn_name #fn_generics (#in_ident) } + }; + let crate_name = quote! { yew_agent }; + + let quoted = quote! { + #(#struct_attrs)* + #[allow(unused_parens)] + #vis struct #oneshot_name #generics #where_clause { + inner: ::std::pin::Pin<::std::boxed::Box>>, + _marker: ::std::marker::PhantomData<(#phantom_generics)>, + } + + // we cannot disable any lints here because it will be applied to the function body + // as well. + #(#oneshot_impl_attrs)* + impl #impl_generics ::#crate_name::oneshot::Oneshot for #oneshot_name #ty_generics #where_clause { + type Input = #input_type; + + fn create(#in_ident: Self::Input) -> Self { + #inner_fn + + Self { + inner: ::std::boxed::Box::pin( + async move { + #fn_call + } + ), + _marker: ::std::marker::PhantomData, + } + } + } + + impl #impl_generics ::std::future::Future for #oneshot_name #ty_generics #where_clause { + type Output = #output_type; + + fn poll(mut self: ::std::pin::Pin<&mut Self>, cx: &mut ::std::task::Context<'_>) -> ::std::task::Poll { + ::std::future::Future::poll(::std::pin::Pin::new(&mut self.inner), cx) + } + } + + impl #impl_generics ::#crate_name::Registrable for #oneshot_name #ty_generics #where_clause { + type Registrar = ::#crate_name::oneshot::OneshotRegistrar; + + fn registrar() -> Self::Registrar { + ::#crate_name::oneshot::OneshotRegistrar::::new() + } + } + + impl #impl_generics ::#crate_name::Spawnable for #oneshot_name #ty_generics #where_clause { + type Spawner = ::#crate_name::oneshot::OneshotSpawner; + + fn spawner() -> Self::Spawner { + ::#crate_name::oneshot::OneshotSpawner::::new() + } + } + }; + + Ok(quoted) +} diff --git a/packages/yew-agent-macro/src/reactor.rs b/packages/yew-agent-macro/src/reactor.rs new file mode 100644 index 00000000000..089e6939f1a --- /dev/null +++ b/packages/yew-agent-macro/src/reactor.rs @@ -0,0 +1,135 @@ +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::{Ident, ReturnType, Signature, Type}; + +use crate::agent_fn::{AgentFn, AgentFnType, AgentName}; + +pub struct ReactorFn {} + +impl AgentFnType for ReactorFn { + type OutputType = (); + type RecvType = Type; + + fn attr_name() -> &'static str { + "reactor" + } + + fn agent_type_name() -> &'static str { + "reactor" + } + + fn parse_recv_type(sig: &Signature) -> syn::Result { + let mut inputs = sig.inputs.iter(); + let arg = inputs + .next() + .ok_or_else(|| syn::Error::new_spanned(&sig.ident, "expected 1 argument"))?; + + let ty = Self::extract_fn_arg_type(arg)?; + + Self::assert_no_left_argument(inputs, 1)?; + + Ok(ty) + } + + fn parse_output_type(sig: &Signature) -> syn::Result { + match &sig.output { + ReturnType::Default => {} + ReturnType::Type(_, ty) => { + return Err(syn::Error::new_spanned( + ty, + "reactor agents cannot return any value", + )) + } + } + + Ok(()) + } +} + +pub fn reactor_impl(name: AgentName, mut agent_fn: AgentFn) -> syn::Result { + agent_fn.merge_agent_name(name)?; + + if !agent_fn.is_async { + return Err(syn::Error::new_spanned( + &agent_fn.name, + "reactor agents must be asynchronous", + )); + } + + let struct_attrs = agent_fn.filter_attrs_for_agent_struct(); + let reactor_impl_attrs = agent_fn.filter_attrs_for_agent_impl(); + let phantom_generics = agent_fn.phantom_generics(); + let reactor_name = agent_fn.agent_name(); + let fn_name = agent_fn.inner_fn_ident(); + let inner_fn = agent_fn.print_inner_fn(); + + let AgentFn { + recv_type, + generics, + vis, + .. + } = agent_fn; + + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let fn_generics = ty_generics.as_turbofish(); + + let scope_ident = Ident::new("_scope", Span::mixed_site()); + + let fn_call = quote! { #fn_name #fn_generics (#scope_ident).await }; + let crate_name = quote! { yew_agent }; + + let quoted = quote! { + #(#struct_attrs)* + #[allow(unused_parens)] + #vis struct #reactor_name #generics #where_clause { + inner: ::std::pin::Pin<::std::boxed::Box>>, + _marker: ::std::marker::PhantomData<(#phantom_generics)>, + } + + // we cannot disable any lints here because it will be applied to the function body + // as well. + #(#reactor_impl_attrs)* + impl #impl_generics ::#crate_name::reactor::Reactor for #reactor_name #ty_generics #where_clause { + type Scope = #recv_type; + + fn create(#scope_ident: Self::Scope) -> Self { + #inner_fn + + Self { + inner: ::std::boxed::Box::pin( + async move { + #fn_call + } + ), + _marker: ::std::marker::PhantomData, + } + } + } + + impl #impl_generics ::std::future::Future for #reactor_name #ty_generics #where_clause { + type Output = (); + + fn poll(mut self: ::std::pin::Pin<&mut Self>, cx: &mut ::std::task::Context<'_>) -> ::std::task::Poll { + ::std::future::Future::poll(::std::pin::Pin::new(&mut self.inner), cx) + } + } + + impl #impl_generics ::#crate_name::Registrable for #reactor_name #ty_generics #where_clause { + type Registrar = ::#crate_name::reactor::ReactorRegistrar; + + fn registrar() -> Self::Registrar { + ::#crate_name::reactor::ReactorRegistrar::::new() + } + } + + impl #impl_generics ::#crate_name::Spawnable for #reactor_name #ty_generics #where_clause { + type Spawner = ::#crate_name::reactor::ReactorSpawner; + + fn spawner() -> Self::Spawner { + ::#crate_name::reactor::ReactorSpawner::::new() + } + } + }; + + Ok(quoted) +} diff --git a/packages/yew-agent/Cargo.toml b/packages/yew-agent/Cargo.toml index 18aef8fa6d3..9bfe65c1d9f 100644 --- a/packages/yew-agent/Cargo.toml +++ b/packages/yew-agent/Cargo.toml @@ -9,10 +9,15 @@ edition = "2021" readme = "../../README.md" description = "Agents for Yew" license = "MIT OR Apache-2.0" +rust-version = "1.64.0" [dependencies] yew = { version = "0.20.0", path = "../yew" } -gloo-worker = "0.1" +gloo-worker = { version = "0.3", features = ["futures"] } +wasm-bindgen = "0.2" +serde = { version = "1", features = ["derive"] } +futures = "0.3" +yew-agent-macro = { version = "0.1", path = "../yew-agent-macro" } [dev-dependencies] serde = "1.0.164" diff --git a/packages/yew-agent/src/hooks.rs b/packages/yew-agent/src/hooks.rs deleted file mode 100644 index 028b385fed1..00000000000 --- a/packages/yew-agent/src/hooks.rs +++ /dev/null @@ -1,132 +0,0 @@ -use std::cell::RefCell; -use std::rc::Rc; - -use yew::prelude::*; - -use crate::*; - -/// State handle for [`use_bridge`] hook -pub struct UseBridgeHandle -where - T: Bridged, -{ - inner: Rc>>>, -} - -impl UseBridgeHandle -where - T: Bridged, -{ - /// Send a message to an worker. - pub fn send(&self, msg: T::Input) { - let mut bridge = self.inner.borrow_mut(); - bridge.send(msg); - } -} - -/// A hook to bridge to an [`Worker`]. -/// -/// This hooks will only bridge the worker once over the entire component lifecycle. -/// -/// Takes a callback as the only argument. The callback will be updated on every render to make -/// sure captured values (if any) are up to date. -/// -/// # Examples -/// -/// ``` -/// # mod example { -/// use serde::{Deserialize, Serialize}; -/// use yew::prelude::*; -/// use yew_agent::{use_bridge, UseBridgeHandle}; -/// -/// // This would usually live in the same file as your worker -/// #[derive(Serialize, Deserialize)] -/// pub enum WorkerResponseType { -/// IncrementCounter, -/// } -/// # mod my_worker_mod { -/// # use yew_agent::{HandlerId, Public, WorkerLink}; -/// # use super::WorkerResponseType; -/// # pub struct MyWorker { -/// # pub link: WorkerLink, -/// # } -/// -/// # impl yew_agent::Worker for MyWorker { -/// # type Input = (); -/// # type Output = WorkerResponseType; -/// # type Reach = Public; -/// # type Message = (); -/// # -/// # fn create(link: WorkerLink) -> Self { -/// # MyWorker { link } -/// # } -/// # -/// # fn update(&mut self, _msg: Self::Message) { -/// # // do nothing -/// # } -/// # -/// # fn handle_input(&mut self, _msg: Self::Input, id: HandlerId) { -/// # self.link.respond(id, WorkerResponseType::IncrementCounter); -/// # } -/// # } -/// # } -/// use my_worker_mod::MyWorker; // note that ::Output == WorkerResponseType -/// #[function_component(UseBridge)] -/// fn bridge() -> Html { -/// let counter = use_state(|| 0); -/// -/// // a scoped block to clone the state in -/// { -/// let counter = counter.clone(); -/// // response will be of type MyWorker::Output, i.e. WorkerResponseType -/// let bridge: UseBridgeHandle = use_bridge(move |response| match response { -/// WorkerResponseType::IncrementCounter => { -/// counter.set(*counter + 1); -/// } -/// }); -/// } -/// -/// html! { -///
-/// {*counter} -///
-/// } -/// } -/// # } -/// ``` -#[hook] -pub fn use_bridge(on_output: F) -> UseBridgeHandle -where - T: Bridged, - F: Fn(T::Output) + 'static, -{ - let on_output = Rc::new(on_output); - - let on_output_clone = on_output.clone(); - let on_output_ref = use_mut_ref(move || on_output_clone); - - // Refresh the callback on every render. - { - let mut on_output_ref = on_output_ref.borrow_mut(); - *on_output_ref = on_output; - } - - let bridge = use_mut_ref(move || { - T::bridge({ - Rc::new(move |output| { - let on_output = on_output_ref.borrow().clone(); - on_output(output); - }) - }) - }); - - UseBridgeHandle { inner: bridge } -} - -impl Clone for UseBridgeHandle { - fn clone(&self) -> Self { - Self { - inner: self.inner.clone(), - } - } -} diff --git a/packages/yew-agent/src/lib.rs b/packages/yew-agent/src/lib.rs index 9a68c12f2cb..160d7d16b81 100644 --- a/packages/yew-agent/src/lib.rs +++ b/packages/yew-agent/src/lib.rs @@ -1,7 +1,112 @@ //! This module contains Yew's web worker implementation. +//! +//! ## Types +//! +//! There're a couple kinds of agents: +//! +//! #### Oneshot +//! +//! A kind of agent that for each input, a single output is returned. +//! +//! #### Reactor +//! +//! A kind of agent that can send many inputs and receive many outputs over a single bridge. +//! +//! #### Worker +//! +//! The low-level implementation of agents that provides an actor model and communicates with +//! multiple bridges. +//! +//! ## Reachability +//! +//! When an agent is spawned, each agent is associated with a reachability. +//! +//! #### Private +//! +//! Each time a bridge is created, a new instance +//! of agent is spawned. This allows parallel computing between agents. +//! +//! #### Public +//! +//! Public agents are shared among all children of a provider. +//! Only 1 instance will be spawned for each public agents provider. +//! +//! ### Provider +//! +//! Each Agent requires a provider to provide communications and maintain bridges. +//! All hooks must be called within a provider. +//! +//! ## Communications with Agents +//! +//! Hooks provides means to communicate with agent instances. +//! +//! #### Bridge +//! +//! See: [`use_worker_bridge`](worker::use_worker_bridge), +//! [`use_reactor_bridge`](reactor::use_reactor_bridge) +//! +//! A bridge takes a callback to receive outputs from agents +//! and provides a handle to send inputs to agents. +//! +//! #### Subscription +//! +//! See: [`use_worker_subscription`](worker::use_worker_subscription), +//! [`use_reactor_subscription`](reactor::use_reactor_subscription) +//! +//! Similar to bridges, a subscription produces a handle to send inputs to agents. However, instead +//! of notifying the receiver with a callback, it collect all outputs into a slice. +//! +//! #### Runner +//! +//! See: [`use_oneshot_runner`](oneshot::use_oneshot_runner) +//! +//! Unlike other agents, oneshot bridges provide a `use_oneshot_runner` hook to execute oneshot +//! agents on demand. -mod hooks; +#![deny( + clippy::all, + missing_docs, + missing_debug_implementations, + bare_trait_objects, + anonymous_parameters, + elided_lifetimes_in_paths +)] + +extern crate self as yew_agent; + +pub mod oneshot; +pub mod reactor; +pub mod worker; #[doc(inline)] -pub use gloo_worker::*; -pub use hooks::{use_bridge, UseBridgeHandle}; +pub use gloo_worker::{Bincode, Codec, Registrable, Spawnable}; + +mod reach; +pub mod scope_ext; + +pub use reach::Reach; + +mod utils; + +#[doc(hidden)] +pub mod __vendored { + pub use futures; +} + +pub mod prelude { + //! Prelude module to be imported when working with `yew-agent`. + //! + //! This module re-exports the frequently used types from the crate. + pub use crate::oneshot::{oneshot, use_oneshot_runner, UseOneshotRunnerHandle}; + pub use crate::reach::Reach; + pub use crate::reactor::{ + reactor, use_reactor_bridge, use_reactor_subscription, ReactorEvent, ReactorScope, + UseReactorBridgeHandle, UseReactorSubscriptionHandle, + }; + pub use crate::scope_ext::{AgentScopeExt, ReactorBridgeHandle, WorkerBridgeHandle}; + pub use crate::worker::{ + use_worker_bridge, use_worker_subscription, UseWorkerBridgeHandle, + UseWorkerSubscriptionHandle, WorkerScope, + }; + pub use crate::{Registrable, Spawnable}; +} diff --git a/packages/yew-agent/src/oneshot/hooks.rs b/packages/yew-agent/src/oneshot/hooks.rs new file mode 100644 index 00000000000..7e6437dc56a --- /dev/null +++ b/packages/yew-agent/src/oneshot/hooks.rs @@ -0,0 +1,54 @@ +use yew::prelude::*; + +use super::provider::OneshotProviderState; +use super::Oneshot; + +/// Hook handle for [`use_oneshot_runner`] +#[derive(Debug)] +pub struct UseOneshotRunnerHandle +where + T: Oneshot + 'static, +{ + state: OneshotProviderState, +} + +impl UseOneshotRunnerHandle +where + T: Oneshot + 'static, +{ + /// Runs an oneshot agent. + pub async fn run(&self, input: T::Input) -> T::Output { + self.state.create_bridge().run(input).await + } +} + +impl Clone for UseOneshotRunnerHandle +where + T: Oneshot + 'static, +{ + fn clone(&self) -> Self { + Self { + state: self.state.clone(), + } + } +} + +impl PartialEq for UseOneshotRunnerHandle +where + T: Oneshot, +{ + fn eq(&self, rhs: &Self) -> bool { + self.state == rhs.state + } +} + +/// A hook to create a runner to an oneshot agent. +#[hook] +pub fn use_oneshot_runner() -> UseOneshotRunnerHandle +where + T: Oneshot + 'static, +{ + let state = use_context::>().expect("failed to find worker context"); + + UseOneshotRunnerHandle { state } +} diff --git a/packages/yew-agent/src/oneshot/mod.rs b/packages/yew-agent/src/oneshot/mod.rs new file mode 100644 index 00000000000..d3c96bb050c --- /dev/null +++ b/packages/yew-agent/src/oneshot/mod.rs @@ -0,0 +1,12 @@ +//! This module provides task agent implementation. + +mod hooks; +mod provider; + +#[doc(inline)] +pub use gloo_worker::oneshot::{Oneshot, OneshotBridge, OneshotRegistrar, OneshotSpawner}; +pub use hooks::{use_oneshot_runner, UseOneshotRunnerHandle}; +pub use provider::OneshotProvider; +pub(crate) use provider::OneshotProviderState; +/// A procedural macro to create oneshot agents. +pub use yew_agent_macro::oneshot; diff --git a/packages/yew-agent/src/oneshot/provider.rs b/packages/yew-agent/src/oneshot/provider.rs new file mode 100644 index 00000000000..b56516669ef --- /dev/null +++ b/packages/yew-agent/src/oneshot/provider.rs @@ -0,0 +1,130 @@ +use core::fmt; +use std::any::type_name; +use std::cell::RefCell; +use std::rc::Rc; + +use serde::{Deserialize, Serialize}; +use yew::prelude::*; + +use super::{Oneshot, OneshotBridge, OneshotSpawner}; +use crate::utils::get_next_id; +use crate::worker::WorkerProviderProps; +use crate::{Bincode, Codec, Reach}; + +pub(crate) struct OneshotProviderState +where + T: Oneshot + 'static, +{ + id: usize, + spawn_bridge_fn: Rc OneshotBridge>, + reach: Reach, + held_bridge: Rc>>>, +} + +impl fmt::Debug for OneshotProviderState +where + T: Oneshot, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(type_name::()) + } +} + +impl OneshotProviderState +where + T: Oneshot, +{ + fn get_held_bridge(&self) -> OneshotBridge { + let mut held_bridge = self.held_bridge.borrow_mut(); + + match held_bridge.as_mut() { + Some(m) => m.fork(), + None => { + let bridge = (self.spawn_bridge_fn)(); + *held_bridge = Some(bridge.fork()); + bridge + } + } + } + + /// Creates a bridge, uses "fork" for public agents. + pub fn create_bridge(&self) -> OneshotBridge { + match self.reach { + Reach::Public => { + let held_bridge = self.get_held_bridge(); + held_bridge.fork() + } + Reach::Private => (self.spawn_bridge_fn)(), + } + } +} + +impl Clone for OneshotProviderState +where + T: Oneshot, +{ + fn clone(&self) -> Self { + Self { + id: self.id, + spawn_bridge_fn: self.spawn_bridge_fn.clone(), + reach: self.reach, + held_bridge: self.held_bridge.clone(), + } + } +} + +impl PartialEq for OneshotProviderState +where + T: Oneshot, +{ + fn eq(&self, rhs: &Self) -> bool { + self.id == rhs.id + } +} + +/// The Oneshot Agent Provider. +/// +/// This component provides its children access to an oneshot agent. +#[function_component] +pub fn OneshotProvider(props: &WorkerProviderProps) -> Html +where + T: Oneshot + 'static, + T::Input: Serialize + for<'de> Deserialize<'de> + 'static, + T::Output: Serialize + for<'de> Deserialize<'de> + 'static, + C: Codec + 'static, +{ + let WorkerProviderProps { + children, + path, + lazy, + reach, + } = props.clone(); + + // Creates a spawning function so Codec is can be erased from contexts. + let spawn_bridge_fn: Rc OneshotBridge> = { + let path = path.clone(); + Rc::new(move || OneshotSpawner::::new().encoding::().spawn(&path)) + }; + + let state = { + use_memo((path, lazy, reach), move |(_path, lazy, reach)| { + let state = OneshotProviderState:: { + id: get_next_id(), + spawn_bridge_fn, + reach: *reach, + held_bridge: Rc::default(), + }; + + if *reach == Reach::Public && !*lazy { + state.get_held_bridge(); + } + state + }) + }; + + html! { + > context={(*state).clone()}> + {children} + >> + } +} diff --git a/packages/yew-agent/src/reach.rs b/packages/yew-agent/src/reach.rs new file mode 100644 index 00000000000..1bab773a503 --- /dev/null +++ b/packages/yew-agent/src/reach.rs @@ -0,0 +1,8 @@ +/// The reachability of an agent. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)] +pub enum Reach { + /// Public Reachability. + Public, + /// Private Reachability. + Private, +} diff --git a/packages/yew-agent/src/reactor/hooks.rs b/packages/yew-agent/src/reactor/hooks.rs new file mode 100644 index 00000000000..975c11abb24 --- /dev/null +++ b/packages/yew-agent/src/reactor/hooks.rs @@ -0,0 +1,280 @@ +use std::any::type_name; +use std::fmt; +use std::ops::Deref; +use std::rc::Rc; + +use futures::sink::SinkExt; +use futures::stream::{SplitSink, StreamExt}; +use wasm_bindgen::UnwrapThrowExt; +use yew::platform::pinned::RwLock; +use yew::platform::spawn_local; +use yew::prelude::*; + +use super::provider::ReactorProviderState; +use super::{Reactor, ReactorBridge, ReactorScoped}; +use crate::utils::{BridgeIdState, OutputsAction, OutputsState}; + +type ReactorTx = + Rc, <::Scope as ReactorScoped>::Input>>>; + +/// A type that represents events from a reactor. +pub enum ReactorEvent +where + R: Reactor, +{ + /// The reactor agent has sent an output. + Output(::Output), + /// The reactor agent has exited. + Finished, +} + +impl fmt::Debug for ReactorEvent +where + R: Reactor, + ::Output: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Output(m) => f.debug_tuple("ReactorEvent::Output").field(&m).finish(), + Self::Finished => f.debug_tuple("ReactorEvent::Finished").finish(), + } + } +} + +/// Hook handle for the [`use_reactor_bridge`] hook. +pub struct UseReactorBridgeHandle +where + R: 'static + Reactor, +{ + tx: ReactorTx, + ctr: UseReducerDispatcher, +} + +impl fmt::Debug for UseReactorBridgeHandle +where + R: 'static + Reactor, + ::Input: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct(type_name::()) + .field("inner", &self.tx) + .finish() + } +} + +impl Clone for UseReactorBridgeHandle +where + R: 'static + Reactor, +{ + fn clone(&self) -> Self { + Self { + tx: self.tx.clone(), + ctr: self.ctr.clone(), + } + } +} + +impl UseReactorBridgeHandle +where + R: 'static + Reactor, +{ + /// Send an input to a reactor agent. + pub fn send(&self, msg: ::Input) { + let tx = self.tx.clone(); + spawn_local(async move { + let mut tx = tx.write().await; + let _ = tx.send(msg).await; + }); + } + + /// Reset the bridge. + /// + /// Disconnect the old bridge and re-connects the agent with a new bridge. + pub fn reset(&self) { + self.ctr.dispatch(()); + } +} + +impl PartialEq for UseReactorBridgeHandle +where + R: 'static + Reactor, +{ + fn eq(&self, rhs: &Self) -> bool { + self.ctr == rhs.ctr + } +} + +/// A hook to bridge to a [`Reactor`]. +/// +/// This hooks will only bridge the reactor once over the entire component lifecycle. +/// +/// Takes a callback as the argument. +/// +/// The callback will be updated on every render to make sure captured values (if any) are up to +/// date. +#[hook] +pub fn use_reactor_bridge(on_output: F) -> UseReactorBridgeHandle +where + R: 'static + Reactor, + F: Fn(ReactorEvent) + 'static, +{ + let ctr = use_reducer(BridgeIdState::default); + + let worker_state = use_context::>() + .expect_throw("cannot find a provider for current agent."); + + let on_output = Rc::new(on_output); + + let on_output_ref = { + let on_output = on_output.clone(); + use_mut_ref(move || on_output) + }; + + // Refresh the callback on every render. + { + let mut on_output_ref = on_output_ref.borrow_mut(); + *on_output_ref = on_output; + } + + let tx = use_memo((worker_state, ctr.inner), |(state, _ctr)| { + let bridge = state.create_bridge(); + + let (tx, mut rx) = bridge.split(); + + spawn_local(async move { + while let Some(m) = rx.next().await { + let on_output = on_output_ref.borrow().clone(); + on_output(ReactorEvent::::Output(m)); + } + + let on_output = on_output_ref.borrow().clone(); + on_output(ReactorEvent::::Finished); + }); + + RwLock::new(tx) + }); + + UseReactorBridgeHandle { + tx: tx.clone(), + ctr: ctr.dispatcher(), + } +} + +/// Hook handle for the [`use_reactor_subscription`] hook. +pub struct UseReactorSubscriptionHandle +where + R: 'static + Reactor, +{ + bridge: UseReactorBridgeHandle, + outputs: Vec::Output>>, + finished: bool, + ctr: usize, +} + +impl UseReactorSubscriptionHandle +where + R: 'static + Reactor, +{ + /// Send an input to a reactor agent. + pub fn send(&self, msg: ::Input) { + self.bridge.send(msg); + } + + /// Returns whether the current bridge has received a finish message. + pub fn finished(&self) -> bool { + self.finished + } + + /// Reset the subscription. + /// + /// This disconnects the old bridge and re-connects the agent with a new bridge. + /// Existing outputs stored in the subscription will also be cleared. + pub fn reset(&self) { + self.bridge.reset(); + } +} + +impl Clone for UseReactorSubscriptionHandle +where + R: 'static + Reactor, +{ + fn clone(&self) -> Self { + Self { + bridge: self.bridge.clone(), + outputs: self.outputs.clone(), + ctr: self.ctr, + finished: self.finished, + } + } +} + +impl fmt::Debug for UseReactorSubscriptionHandle +where + R: 'static + Reactor, + ::Input: fmt::Debug, + ::Output: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct(type_name::()) + .field("bridge", &self.bridge) + .field("outputs", &self.outputs) + .finish() + } +} + +impl Deref for UseReactorSubscriptionHandle +where + R: 'static + Reactor, +{ + type Target = [Rc<::Output>]; + + fn deref(&self) -> &Self::Target { + &self.outputs + } +} + +impl PartialEq for UseReactorSubscriptionHandle +where + R: 'static + Reactor, +{ + fn eq(&self, rhs: &Self) -> bool { + self.bridge == rhs.bridge && self.ctr == rhs.ctr + } +} + +/// A hook to subscribe to the outputs of a [Reactor] agent. +/// +/// All outputs sent to current bridge will be collected into a slice. +#[hook] +pub fn use_reactor_subscription() -> UseReactorSubscriptionHandle +where + R: 'static + Reactor, +{ + let outputs = use_reducer(OutputsState::<::Output>::default); + + let bridge = { + let outputs = outputs.clone(); + use_reactor_bridge::(move |output| { + outputs.dispatch(match output { + ReactorEvent::Output(m) => OutputsAction::Push(m.into()), + ReactorEvent::Finished => OutputsAction::Close, + }) + }) + }; + + { + let outputs = outputs.clone(); + use_effect_with(bridge.clone(), move |_| { + outputs.dispatch(OutputsAction::Reset); + + || {} + }); + } + + UseReactorSubscriptionHandle { + bridge, + outputs: outputs.inner.clone(), + ctr: outputs.ctr, + finished: outputs.closed, + } +} diff --git a/packages/yew-agent/src/reactor/mod.rs b/packages/yew-agent/src/reactor/mod.rs new file mode 100644 index 00000000000..cd97555abb8 --- /dev/null +++ b/packages/yew-agent/src/reactor/mod.rs @@ -0,0 +1,53 @@ +//! This module contains the reactor agent implementation. +//! +//! Reactor agents are agents that receive multiple inputs and send multiple outputs over a single +//! bridge. A reactor is defined as an async function that takes a [ReactorScope] +//! as the argument. +//! +//! The reactor scope is a stream that produces inputs from the bridge and a +//! sink that implements an additional send method to send outputs to the connected bridge. +//! When the bridge disconnects, the output stream and input sink will be closed. +//! +//! # Example +//! +//! ``` +//! # use serde::{Serialize, Deserialize}; +//! # #[derive(Serialize, Deserialize)] +//! # pub struct ReactorInput {} +//! # #[derive(Serialize, Deserialize)] +//! # pub struct ReactorOutput {} +//! # +//! use futures::sink::SinkExt; +//! use futures::stream::StreamExt; +//! use yew_agent::reactor::{reactor, ReactorScope}; +//! #[reactor(MyReactor)] +//! pub async fn my_reactor(mut scope: ReactorScope) { +//! while let Some(input) = scope.next().await { +//! // handles each input. +//! // ... +//! # let output = ReactorOutput { /* ... */ }; +//! +//! // sends output +//! if scope.send(output).await.is_err() { +//! // sender closed, the bridge is disconnected +//! break; +//! } +//! } +//! } +//! ``` + +mod hooks; +mod provider; + +#[doc(inline)] +pub use gloo_worker::reactor::{ + Reactor, ReactorBridge, ReactorRegistrar, ReactorScope, ReactorScoped, ReactorSpawner, +}; +pub use hooks::{ + use_reactor_bridge, use_reactor_subscription, ReactorEvent, UseReactorBridgeHandle, + UseReactorSubscriptionHandle, +}; +pub use provider::ReactorProvider; +pub(crate) use provider::ReactorProviderState; +/// A procedural macro to create reactor agents. +pub use yew_agent_macro::reactor; diff --git a/packages/yew-agent/src/reactor/provider.rs b/packages/yew-agent/src/reactor/provider.rs new file mode 100644 index 00000000000..03ec9008ac2 --- /dev/null +++ b/packages/yew-agent/src/reactor/provider.rs @@ -0,0 +1,133 @@ +use std::any::type_name; +use std::cell::RefCell; +use std::fmt; +use std::rc::Rc; + +use gloo_worker::reactor::ReactorScoped; +use serde::{Deserialize, Serialize}; +use yew::prelude::*; + +use super::{Reactor, ReactorBridge, ReactorSpawner}; +use crate::utils::get_next_id; +use crate::worker::WorkerProviderProps; +use crate::{Bincode, Codec, Reach}; + +pub(crate) struct ReactorProviderState +where + T: Reactor + 'static, +{ + id: usize, + spawn_bridge_fn: Rc ReactorBridge>, + reach: Reach, + held_bridge: Rc>>>, +} + +impl fmt::Debug for ReactorProviderState +where + T: Reactor, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(type_name::()) + } +} + +impl ReactorProviderState +where + T: Reactor, +{ + fn get_held_bridge(&self) -> ReactorBridge { + let mut held_bridge = self.held_bridge.borrow_mut(); + + match held_bridge.as_mut() { + Some(m) => m.fork(), + None => { + let bridge = (self.spawn_bridge_fn)(); + *held_bridge = Some(bridge.fork()); + bridge + } + } + } + + /// Creates a bridge, uses "fork" for public agents. + pub fn create_bridge(&self) -> ReactorBridge { + match self.reach { + Reach::Public => { + let held_bridge = self.get_held_bridge(); + held_bridge.fork() + } + Reach::Private => (self.spawn_bridge_fn)(), + } + } +} + +impl Clone for ReactorProviderState +where + T: Reactor, +{ + fn clone(&self) -> Self { + Self { + id: self.id, + spawn_bridge_fn: self.spawn_bridge_fn.clone(), + reach: self.reach, + held_bridge: self.held_bridge.clone(), + } + } +} + +impl PartialEq for ReactorProviderState +where + T: Reactor, +{ + fn eq(&self, rhs: &Self) -> bool { + self.id == rhs.id + } +} + +/// The Reactor Agent Provider. +/// +/// This component provides its children access to a reactor agent. +#[function_component] +pub fn ReactorProvider(props: &WorkerProviderProps) -> Html +where + R: 'static + Reactor, + <::Scope as ReactorScoped>::Input: + Serialize + for<'de> Deserialize<'de> + 'static, + <::Scope as ReactorScoped>::Output: + Serialize + for<'de> Deserialize<'de> + 'static, + C: Codec + 'static, +{ + let WorkerProviderProps { + children, + path, + lazy, + reach, + } = props.clone(); + + // Creates a spawning function so Codec is can be erased from contexts. + let spawn_bridge_fn: Rc ReactorBridge> = { + let path = path.clone(); + Rc::new(move || ReactorSpawner::::new().encoding::().spawn(&path)) + }; + + let state = { + use_memo((path, lazy, reach), move |(_path, lazy, reach)| { + let state = ReactorProviderState:: { + id: get_next_id(), + spawn_bridge_fn, + reach: *reach, + held_bridge: Rc::default(), + }; + + if *reach == Reach::Public && !*lazy { + state.get_held_bridge(); + } + state + }) + }; + + html! { + > context={(*state).clone()}> + {children} + >> + } +} diff --git a/packages/yew-agent/src/scope_ext.rs b/packages/yew-agent/src/scope_ext.rs new file mode 100644 index 00000000000..6120062f9c6 --- /dev/null +++ b/packages/yew-agent/src/scope_ext.rs @@ -0,0 +1,145 @@ +//! This module contains extensions to the component scope for agent access. + +use std::any::type_name; +use std::fmt; +use std::rc::Rc; + +use futures::stream::SplitSink; +use futures::{SinkExt, StreamExt}; +use wasm_bindgen::UnwrapThrowExt; +use yew::html::Scope; +use yew::platform::pinned::RwLock; +use yew::platform::spawn_local; +use yew::prelude::*; + +use crate::oneshot::{Oneshot, OneshotProviderState}; +use crate::reactor::{Reactor, ReactorBridge, ReactorEvent, ReactorProviderState, ReactorScoped}; +use crate::worker::{Worker, WorkerBridge, WorkerProviderState}; + +/// A Worker Bridge Handle. +#[derive(Debug)] +pub struct WorkerBridgeHandle +where + W: Worker, +{ + inner: WorkerBridge, +} + +impl WorkerBridgeHandle +where + W: Worker, +{ + /// Sends a message to the worker agent. + pub fn send(&self, input: W::Input) { + self.inner.send(input) + } +} + +type ReactorTx = + Rc, <::Scope as ReactorScoped>::Input>>>; + +/// A Reactor Bridge Handle. +pub struct ReactorBridgeHandle +where + R: Reactor + 'static, +{ + tx: ReactorTx, +} + +impl fmt::Debug for ReactorBridgeHandle +where + R: Reactor + 'static, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct(type_name::()).finish_non_exhaustive() + } +} + +impl ReactorBridgeHandle +where + R: Reactor + 'static, +{ + /// Sends a message to the reactor agent. + pub fn send(&self, input: ::Input) { + let tx = self.tx.clone(); + spawn_local(async move { + let mut tx = tx.write().await; + let _ = tx.send(input).await; + }); + } +} + +/// An extension to [`Scope`](yew::html::Scope) that provides communication mechanism to agents. +/// +/// You can access them on `ctx.link()` +pub trait AgentScopeExt { + /// Bridges to a Worker Agent. + fn bridge_worker(&self, callback: Callback) -> WorkerBridgeHandle + where + W: Worker + 'static; + + /// Bridges to a Reactor Agent. + fn bridge_reactor(&self, callback: Callback>) -> ReactorBridgeHandle + where + R: Reactor + 'static, + ::Output: 'static; + + /// Runs an oneshot in an Oneshot Agent. + fn run_oneshot(&self, input: T::Input, callback: Callback) + where + T: Oneshot + 'static; +} + +impl AgentScopeExt for Scope +where + COMP: Component, +{ + fn bridge_worker(&self, callback: Callback) -> WorkerBridgeHandle + where + W: Worker + 'static, + { + let inner = self + .context::>((|_| {}).into()) + .expect_throw("failed to bridge to agent.") + .0 + .create_bridge(callback); + + WorkerBridgeHandle { inner } + } + + fn bridge_reactor(&self, callback: Callback>) -> ReactorBridgeHandle + where + R: Reactor + 'static, + ::Output: 'static, + { + let (tx, mut rx) = self + .context::>((|_| {}).into()) + .expect_throw("failed to bridge to agent.") + .0 + .create_bridge() + .split(); + + spawn_local(async move { + while let Some(m) = rx.next().await { + callback.emit(ReactorEvent::::Output(m)); + } + + callback.emit(ReactorEvent::::Finished); + }); + + let tx = Rc::new(RwLock::new(tx)); + + ReactorBridgeHandle { tx } + } + + fn run_oneshot(&self, input: T::Input, callback: Callback) + where + T: Oneshot + 'static, + { + let (inner, _) = self + .context::>((|_| {}).into()) + .expect_throw("failed to bridge to agent."); + + spawn_local(async move { callback.emit(inner.create_bridge().run(input).await) }); + } +} diff --git a/packages/yew-agent/src/utils.rs b/packages/yew-agent/src/utils.rs new file mode 100644 index 00000000000..5dfefb020df --- /dev/null +++ b/packages/yew-agent/src/utils.rs @@ -0,0 +1,83 @@ +use std::rc::Rc; +use std::sync::atomic::{AtomicUsize, Ordering}; + +use yew::Reducible; + +/// Gets a unique worker id +pub(crate) fn get_next_id() -> usize { + static CTR: AtomicUsize = AtomicUsize::new(0); + + CTR.fetch_add(1, Ordering::SeqCst) +} + +#[derive(Default, PartialEq)] +pub(crate) struct BridgeIdState { + pub inner: usize, +} + +impl Reducible for BridgeIdState { + type Action = (); + + fn reduce(self: Rc, _: Self::Action) -> Rc { + Self { + inner: self.inner + 1, + } + .into() + } +} + +pub(crate) enum OutputsAction { + Push(Rc), + Close, + Reset, +} + +pub(crate) struct OutputsState { + pub ctr: usize, + pub inner: Vec>, + pub closed: bool, +} + +impl Clone for OutputsState { + fn clone(&self) -> Self { + Self { + ctr: self.ctr, + inner: self.inner.clone(), + closed: self.closed, + } + } +} + +impl Reducible for OutputsState { + type Action = OutputsAction; + + fn reduce(mut self: Rc, action: Self::Action) -> Rc { + { + let this = Rc::make_mut(&mut self); + this.ctr += 1; + + match action { + OutputsAction::Push(m) => this.inner.push(m), + OutputsAction::Close => { + this.closed = true; + } + OutputsAction::Reset => { + this.closed = false; + this.inner = Vec::new(); + } + } + } + + self + } +} + +impl Default for OutputsState { + fn default() -> Self { + Self { + ctr: 0, + inner: Vec::new(), + closed: false, + } + } +} diff --git a/packages/yew-agent/src/worker/hooks.rs b/packages/yew-agent/src/worker/hooks.rs new file mode 100644 index 00000000000..19745e64dfd --- /dev/null +++ b/packages/yew-agent/src/worker/hooks.rs @@ -0,0 +1,219 @@ +use std::any::type_name; +use std::fmt; +use std::ops::Deref; +use std::rc::Rc; + +use wasm_bindgen::prelude::*; +use yew::prelude::*; + +use crate::utils::{BridgeIdState, OutputsAction, OutputsState}; +use crate::worker::provider::WorkerProviderState; +use crate::worker::{Worker, WorkerBridge}; + +/// Hook handle for the [`use_worker_bridge`] hook. +pub struct UseWorkerBridgeHandle +where + T: Worker, +{ + inner: WorkerBridge, + ctr: UseReducerDispatcher, +} + +impl UseWorkerBridgeHandle +where + T: Worker, +{ + /// Send an input to a worker agent. + pub fn send(&self, msg: T::Input) { + self.inner.send(msg); + } + + /// Reset the bridge. + /// + /// Disconnect the old bridge and re-connects the agent with a new bridge. + pub fn reset(&self) { + self.ctr.dispatch(()); + } +} + +impl Clone for UseWorkerBridgeHandle +where + T: Worker, +{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + ctr: self.ctr.clone(), + } + } +} + +impl fmt::Debug for UseWorkerBridgeHandle +where + T: Worker, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct(type_name::()) + .field("inner", &self.inner) + .finish() + } +} + +impl PartialEq for UseWorkerBridgeHandle +where + T: Worker, +{ + fn eq(&self, rhs: &Self) -> bool { + self.inner == rhs.inner + } +} + +/// A hook to bridge to a [`Worker`]. +/// +/// This hooks will only bridge the worker once over the entire component lifecycle. +/// +/// Takes a callback as the argument. +/// +/// The callback will be updated on every render to make sure captured values (if any) are up to +/// date. +#[hook] +pub fn use_worker_bridge(on_output: F) -> UseWorkerBridgeHandle +where + T: Worker + 'static, + F: Fn(T::Output) + 'static, +{ + let ctr = use_reducer(BridgeIdState::default); + + let worker_state = use_context::>() + .expect_throw("cannot find a provider for current agent."); + + let on_output = Rc::new(on_output); + + let on_output_clone = on_output.clone(); + let on_output_ref = use_mut_ref(move || on_output_clone); + + // Refresh the callback on every render. + { + let mut on_output_ref = on_output_ref.borrow_mut(); + *on_output_ref = on_output; + } + + let bridge = use_memo((worker_state, ctr.inner), |(state, _ctr)| { + state.create_bridge(Callback::from(move |output| { + let on_output = on_output_ref.borrow().clone(); + on_output(output); + })) + }); + + UseWorkerBridgeHandle { + inner: (*bridge).clone(), + ctr: ctr.dispatcher(), + } +} + +/// Hook handle for the [`use_worker_subscription`] hook. +pub struct UseWorkerSubscriptionHandle +where + T: Worker, +{ + bridge: UseWorkerBridgeHandle, + outputs: Vec>, + ctr: usize, +} + +impl UseWorkerSubscriptionHandle +where + T: Worker, +{ + /// Send an input to a worker agent. + pub fn send(&self, msg: T::Input) { + self.bridge.send(msg); + } + + /// Reset the subscription. + /// + /// This disconnects the old bridge and re-connects the agent with a new bridge. + /// Existing outputs stored in the subscription will also be cleared. + pub fn reset(&self) { + self.bridge.reset(); + } +} + +impl Clone for UseWorkerSubscriptionHandle +where + T: Worker, +{ + fn clone(&self) -> Self { + Self { + bridge: self.bridge.clone(), + outputs: self.outputs.clone(), + ctr: self.ctr, + } + } +} + +impl fmt::Debug for UseWorkerSubscriptionHandle +where + T: Worker, + T::Output: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct(type_name::()) + .field("bridge", &self.bridge) + .field("outputs", &self.outputs) + .finish() + } +} + +impl Deref for UseWorkerSubscriptionHandle +where + T: Worker, +{ + type Target = [Rc]; + + fn deref(&self) -> &[Rc] { + &self.outputs + } +} + +impl PartialEq for UseWorkerSubscriptionHandle +where + T: Worker, +{ + fn eq(&self, rhs: &Self) -> bool { + self.bridge == rhs.bridge && self.ctr == rhs.ctr + } +} + +/// A hook to subscribe to the outputs of a [Worker] agent. +/// +/// All outputs sent to current bridge will be collected into a slice. +#[hook] +pub fn use_worker_subscription() -> UseWorkerSubscriptionHandle +where + T: Worker + 'static, +{ + let outputs = use_reducer(OutputsState::default); + + let bridge = { + let outputs = outputs.clone(); + use_worker_bridge::(move |output| { + outputs.dispatch(OutputsAction::Push(Rc::new(output))) + }) + }; + + { + let outputs_dispatcher = outputs.dispatcher(); + use_effect_with(bridge.clone(), move |_| { + outputs_dispatcher.dispatch(OutputsAction::Reset); + + || {} + }); + } + + UseWorkerSubscriptionHandle { + bridge, + outputs: outputs.inner.clone(), + ctr: outputs.ctr, + } +} diff --git a/packages/yew-agent/src/worker/mod.rs b/packages/yew-agent/src/worker/mod.rs new file mode 100644 index 00000000000..61603c62781 --- /dev/null +++ b/packages/yew-agent/src/worker/mod.rs @@ -0,0 +1,77 @@ +//! This module contains the worker agent implementation. +//! +//! This is a low-level implementation that uses an actor model. +//! +//! # Example +//! +//! ``` +//! # mod example { +//! use serde::{Deserialize, Serialize}; +//! use yew::prelude::*; +//! use yew_agent::worker::{use_worker_bridge, UseWorkerBridgeHandle}; +//! +//! // This would usually live in the same file as your worker +//! #[derive(Serialize, Deserialize)] +//! pub enum WorkerResponseType { +//! IncrementCounter, +//! } +//! # mod my_worker_mod { +//! # use yew_agent::worker::{HandlerId, WorkerScope}; +//! # use super::WorkerResponseType; +//! # pub struct MyWorker {} +//! # +//! # impl yew_agent::worker::Worker for MyWorker { +//! # type Input = (); +//! # type Output = WorkerResponseType; +//! # type Message = (); +//! # +//! # fn create(scope: &WorkerScope) -> Self { +//! # MyWorker {} +//! # } +//! # +//! # fn update(&mut self, scope: &WorkerScope, _msg: Self::Message) { +//! # // do nothing +//! # } +//! # +//! # fn received(&mut self, scope: &WorkerScope, _msg: Self::Input, id: HandlerId) { +//! # scope.respond(id, WorkerResponseType::IncrementCounter); +//! # } +//! # } +//! # } +//! use my_worker_mod::MyWorker; // note that ::Output == WorkerResponseType +//! #[function_component(UseWorkerBridge)] +//! fn bridge() -> Html { +//! let counter = use_state(|| 0); +//! +//! // a scoped block to clone the state in +//! { +//! let counter = counter.clone(); +//! // response will be of type MyWorker::Output, i.e. WorkerResponseType +//! let bridge: UseWorkerBridgeHandle = use_worker_bridge(move |response| match response { +//! WorkerResponseType::IncrementCounter => { +//! counter.set(*counter + 1); +//! } +//! }); +//! } +//! +//! html! { +//!
+//! {*counter} +//!
+//! } +//! } +//! # } +//! ``` + +mod hooks; +mod provider; + +#[doc(inline)] +pub use gloo_worker::{ + HandlerId, Worker, WorkerBridge, WorkerDestroyHandle, WorkerRegistrar, WorkerScope, +}; +pub use hooks::{ + use_worker_bridge, use_worker_subscription, UseWorkerBridgeHandle, UseWorkerSubscriptionHandle, +}; +pub(crate) use provider::WorkerProviderState; +pub use provider::{WorkerProvider, WorkerProviderProps}; diff --git a/packages/yew-agent/src/worker/provider.rs b/packages/yew-agent/src/worker/provider.rs new file mode 100644 index 00000000000..b452729d027 --- /dev/null +++ b/packages/yew-agent/src/worker/provider.rs @@ -0,0 +1,159 @@ +use std::any::type_name; +use std::cell::RefCell; +use std::fmt; +use std::rc::Rc; + +use gloo_worker::Spawnable; +use serde::{Deserialize, Serialize}; +use yew::prelude::*; + +use super::{Worker, WorkerBridge}; +use crate::reach::Reach; +use crate::utils::get_next_id; +use crate::{Bincode, Codec}; + +/// Properties for [WorkerProvider]. +#[derive(Debug, Properties, PartialEq, Clone)] +pub struct WorkerProviderProps { + /// The path to an agent. + pub path: AttrValue, + + /// The reachability of an agent. + /// + /// Default: [`Public`](Reach::Public). + #[prop_or(Reach::Public)] + pub reach: Reach, + + /// Lazily spawn the agent. + /// + /// The agent will be spawned when the first time a hook requests a bridge. + /// + /// Does not affect private agents. + /// + /// Default: `true` + #[prop_or(true)] + pub lazy: bool, + + /// Children of the provider. + #[prop_or_default] + pub children: Html, +} + +pub(crate) struct WorkerProviderState +where + W: Worker, +{ + id: usize, + spawn_bridge_fn: Rc WorkerBridge>, + reach: Reach, + held_bridge: Rc>>>, +} + +impl fmt::Debug for WorkerProviderState +where + W: Worker, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(type_name::()) + } +} + +impl WorkerProviderState +where + W: Worker, + W::Output: 'static, +{ + fn get_held_bridge(&self) -> WorkerBridge { + let mut held_bridge = self.held_bridge.borrow_mut(); + + match held_bridge.as_mut() { + Some(m) => m.clone(), + None => { + let bridge = (self.spawn_bridge_fn)(); + *held_bridge = Some(bridge.clone()); + bridge + } + } + } + + /// Creates a bridge, uses "fork" for public agents. + pub fn create_bridge(&self, cb: Callback) -> WorkerBridge { + match self.reach { + Reach::Public => { + let held_bridge = self.get_held_bridge(); + held_bridge.fork(Some(move |m| cb.emit(m))) + } + Reach::Private => (self.spawn_bridge_fn)(), + } + } +} + +impl Clone for WorkerProviderState +where + W: Worker, +{ + fn clone(&self) -> Self { + Self { + id: self.id, + spawn_bridge_fn: self.spawn_bridge_fn.clone(), + reach: self.reach, + held_bridge: self.held_bridge.clone(), + } + } +} + +impl PartialEq for WorkerProviderState +where + W: Worker, +{ + fn eq(&self, rhs: &Self) -> bool { + self.id == rhs.id + } +} + +/// The Worker Agent Provider. +/// +/// This component provides its children access to a worker agent. +#[function_component] +pub fn WorkerProvider(props: &WorkerProviderProps) -> Html +where + W: Worker + 'static, + W::Input: Serialize + for<'de> Deserialize<'de> + 'static, + W::Output: Serialize + for<'de> Deserialize<'de> + 'static, + C: Codec + 'static, +{ + let WorkerProviderProps { + children, + path, + lazy, + reach, + } = props.clone(); + + // Creates a spawning function so Codec is can be erased from contexts. + let spawn_bridge_fn: Rc WorkerBridge> = { + let path = path.clone(); + Rc::new(move || W::spawner().encoding::().spawn(&path)) + }; + + let state = { + use_memo((path, lazy, reach), move |(_path, lazy, reach)| { + let state = WorkerProviderState:: { + id: get_next_id(), + spawn_bridge_fn, + reach: *reach, + held_bridge: Rc::default(), + }; + + if *reach == Reach::Public && !*lazy { + state.get_held_bridge(); + } + state + }) + }; + + html! { + > context={(*state).clone()}> + {children} + >> + } +} From e249128f1274d97c0714b307e706042c2a48fc85 Mon Sep 17 00:00:00 2001 From: Daniel Sousa Date: Thu, 21 Sep 2023 13:30:20 +0100 Subject: [PATCH 02/14] Remove whitespace in website tutorial (#3402) * Remove whitespace in website tutorial * Update index.mdx Remove whitespace in tutorial. --- website/docs/tutorial/index.mdx | 2 +- website/versioned_docs/version-0.20/tutorial/index.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/tutorial/index.mdx b/website/docs/tutorial/index.mdx index 67146c3e2ad..9bf1c2c34bd 100644 --- a/website/docs/tutorial/index.mdx +++ b/website/docs/tutorial/index.mdx @@ -107,7 +107,7 @@ Now, let's create an `index.html` at the root of the project. ```html title="index.html" - + ``` diff --git a/website/versioned_docs/version-0.20/tutorial/index.mdx b/website/versioned_docs/version-0.20/tutorial/index.mdx index 1e8c398b7ef..83e70685449 100644 --- a/website/versioned_docs/version-0.20/tutorial/index.mdx +++ b/website/versioned_docs/version-0.20/tutorial/index.mdx @@ -107,7 +107,7 @@ Now, let's create an `index.html` at the root of the project. ```html title="index.html" - + ``` From b71dbfe17ed8a1237414aeb9176233060ace46d7 Mon Sep 17 00:00:00 2001 From: Daniel Sousa Date: Sat, 23 Sep 2023 13:34:11 +0100 Subject: [PATCH 03/14] Fix failing doc test in migration guide (#3404) * Remove error: doctest failed, to rerun pass `-p website-test --doc` (#3404) Changes to be committed: modified: website/docs/migration-guides/yew/from-0_18_0-to-0_19_0.mdx --- website/docs/migration-guides/yew/from-0_18_0-to-0_19_0.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/migration-guides/yew/from-0_18_0-to-0_19_0.mdx b/website/docs/migration-guides/yew/from-0_18_0-to-0_19_0.mdx index 85c4bc26c67..7e6e96c534c 100644 --- a/website/docs/migration-guides/yew/from-0_18_0-to-0_19_0.mdx +++ b/website/docs/migration-guides/yew/from-0_18_0-to-0_19_0.mdx @@ -17,7 +17,7 @@ props with braces. -```rust {4}, ignore +```rust ,ignore {4} let super_age = 1; html!{ -```rust {4}, ignore +```rust ,ignore {4} let super_age = 1; html!{ Date: Sat, 23 Sep 2023 13:34:30 +0100 Subject: [PATCH 04/14] Remove special handing of struct fields of type `Option` in `derive(Properties)` (#3398) * removed PropAttr::Option * fixed formatting * removed an irrelevant test * added a test for converting value into Some(value) in the html! macro * added more tests for derive(Properties) * added more tests (again) --- packages/yew-macro/src/derive_props/field.rs | 98 +------------------ packages/yew-macro/tests/derive_props/fail.rs | 12 +++ .../yew-macro/tests/derive_props/fail.stderr | 79 ++++++++++----- packages/yew-macro/tests/derive_props/pass.rs | 23 ++++- packages/yew/src/suspense/component.rs | 1 + 5 files changed, 93 insertions(+), 120 deletions(-) diff --git a/packages/yew-macro/src/derive_props/field.rs b/packages/yew-macro/src/derive_props/field.rs index 4f8fd9186c9..37dc28c8bc3 100644 --- a/packages/yew-macro/src/derive_props/field.rs +++ b/packages/yew-macro/src/derive_props/field.rs @@ -5,10 +5,7 @@ use proc_macro2::{Ident, Span}; use quote::{format_ident, quote, quote_spanned}; use syn::parse::Result; use syn::spanned::Spanned; -use syn::{ - parse_quote, Attribute, Error, Expr, Field, GenericParam, Generics, Path, Type, TypePath, - Visibility, -}; +use syn::{parse_quote, Attribute, Error, Expr, Field, GenericParam, Generics, Type, Visibility}; use super::should_preserve_attr; use crate::derive_props::generics::push_type_param; @@ -17,7 +14,6 @@ use crate::derive_props::generics::push_type_param; #[derive(PartialEq, Eq)] enum PropAttr { Required { wrapped_name: Ident }, - Option, PropOr(Expr), PropOrElse(Expr), PropOrDefault, @@ -82,11 +78,6 @@ impl PropField { #name: ::std::option::Option::unwrap(this.wrapped.#wrapped_name), } } - PropAttr::Option => { - quote! { - #name: this.wrapped.#name, - } - } PropAttr::PropOr(value) => { quote_spanned! {value.span()=> #name: ::std::option::Option::unwrap_or(this.wrapped.#name, #value), @@ -115,19 +106,9 @@ impl PropField { let ty = &self.ty; let extra_attrs = &self.extra_attrs; let wrapped_name = self.wrapped_name(); - match &self.attr { - PropAttr::Option => { - quote! { - #( #extra_attrs )* - #wrapped_name: #ty, - } - } - _ => { - quote! { - #( #extra_attrs )* - #wrapped_name: ::std::option::Option<#ty>, - } - } + quote! { + #( #extra_attrs )* + #wrapped_name: ::std::option::Option<#ty>, } } @@ -164,19 +145,6 @@ impl PropField { } } } - PropAttr::Option => { - quote! { - #[doc(hidden)] - #vis fn #name<#token_ty>( - &mut self, - token: #token_ty, - value: impl ::yew::html::IntoPropValue<#ty>, - ) -> #token_ty { - self.wrapped.#name = value.into_prop_value(); - token - } - } - } _ => { quote! { #[doc(hidden)] @@ -216,12 +184,6 @@ impl PropField { } else { unreachable!() } - } else if matches!( - &named_field.ty, - Type::Path(TypePath { path, .. }) - if is_path_an_option(path) - ) { - Ok(PropAttr::Option) } else { let ident = named_field.ident.as_ref().unwrap(); let wrapped_name = format_ident!("{}_wrapper", ident, span = Span::mixed_site()); @@ -294,36 +256,6 @@ impl<'a> PropFieldCheck<'a> { } } -fn is_path_segments_an_option(path_segments: impl Iterator) -> bool { - fn is_option_path_seg(seg_index: usize, path: &str) -> u8 { - match (seg_index, path) { - (0, "core") => 0b001, - (0, "std") => 0b001, - (0, "Option") => 0b111, - (1, "option") => 0b010, - (2, "Option") => 0b100, - _ => 0, - } - } - - path_segments - .enumerate() - .fold(0, |flags, (i, ps)| flags | is_option_path_seg(i, &ps)) - == 0b111 -} - -/// Returns true when the [`Path`] seems like an [`Option`] type. -/// -/// This function considers the following paths as Options: -/// - core::option::Option -/// - std::option::Option -/// - Option::* -/// -/// Users can define their own [`Option`] type and this will return true - this is unavoidable. -fn is_path_an_option(path: &Path) -> bool { - is_path_segments_an_option(path.segments.iter().take(3).map(|ps| ps.ident.to_string())) -} - impl TryFrom for PropField { type Error = Error; @@ -369,25 +301,3 @@ impl PartialEq for PropField { self.name == other.name } } - -#[cfg(test)] -mod tests { - use crate::derive_props::field::is_path_segments_an_option; - - #[test] - fn all_std_and_core_option_path_seg_return_true() { - assert!(is_path_segments_an_option( - vec!["core".to_owned(), "option".to_owned(), "Option".to_owned()].into_iter() - )); - assert!(is_path_segments_an_option( - vec!["std".to_owned(), "option".to_owned(), "Option".to_owned()].into_iter() - )); - assert!(is_path_segments_an_option( - vec!["Option".to_owned()].into_iter() - )); - // why OR instead of XOR - assert!(is_path_segments_an_option( - vec!["Option".to_owned(), "Vec".to_owned(), "Option".to_owned()].into_iter() - )); - } -} diff --git a/packages/yew-macro/tests/derive_props/fail.rs b/packages/yew-macro/tests/derive_props/fail.rs index bba6ab1cab5..93acb335801 100644 --- a/packages/yew-macro/tests/derive_props/fail.rs +++ b/packages/yew-macro/tests/derive_props/fail.rs @@ -36,6 +36,18 @@ mod t3 { } } +mod t4 { + use super::*; + #[derive(Clone, Properties, PartialEq)] + pub struct Props { + value: Option + } + + fn required_option_should_be_provided() { + ::yew::props!{ Props { } }; + } +} + mod t5 { use super::*; #[derive(Clone, Properties, PartialEq)] diff --git a/packages/yew-macro/tests/derive_props/fail.stderr b/packages/yew-macro/tests/derive_props/fail.stderr index 441b184c78d..881609aeaf9 100644 --- a/packages/yew-macro/tests/derive_props/fail.stderr +++ b/packages/yew-macro/tests/derive_props/fail.stderr @@ -1,7 +1,7 @@ error: unexpected end of input, expected expression - --> tests/derive_props/fail.rs:44:19 + --> tests/derive_props/fail.rs:56:19 | -44 | #[prop_or()] +56 | #[prop_or()] | ^ error: cannot find attribute `props` in this scope @@ -11,18 +11,18 @@ error: cannot find attribute `props` in this scope | ^^^^^ error[E0425]: cannot find value `foo` in this scope - --> tests/derive_props/fail.rs:74:24 + --> tests/derive_props/fail.rs:86:24 | -74 | #[prop_or_else(foo)] +86 | #[prop_or_else(foo)] | ^^^ not found in this scope | note: these functions exist but are inaccessible - --> tests/derive_props/fail.rs:88:5 + --> tests/derive_props/fail.rs:100:5 | -88 | fn foo(bar: i32) -> String { +100 | fn foo(bar: i32) -> String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `crate::t9::foo`: not accessible ... -102 | fn foo() -> i32 { +114 | fn foo() -> i32 { | ^^^^^^^^^^^^^^^ `crate::t10::foo`: not accessible error[E0277]: the trait bound `Value: Default` is not satisfied @@ -107,10 +107,39 @@ note: required by a bound in `html::component::properties::__macro::PreBuild::::build` = note: this error originates in the derive macro `Properties` (in Nightly builds, run with -Z macro-backtrace for more info) +error[E0277]: the trait bound `AssertAllProps: HasProp` is not satisfied + --> tests/derive_props/fail.rs:47:24 + | +47 | ::yew::props!{ Props { } }; + | ^^^^^ the trait `HasProp` is not implemented for `AssertAllProps` + | + = help: the following other types implement trait `HasProp`: + as HasProp>> + as HasProp>> + as HasProp>> + as HasProp>> + as HasProp>> + as HasProp>> + as HasProp>> + as HasProp>> + and $N others +note: required because of the requirements on the impl of `HasAllProps` for `t4::CheckPropsAll` + --> tests/derive_props/fail.rs:41:21 + | +41 | #[derive(Clone, Properties, PartialEq)] + | ^^^^^^^^^^ + = note: required because of the requirements on the impl of `AllPropsFor` for `AssertAllProps` +note: required by a bound in `html::component::properties::__macro::PreBuild::::build` + --> $WORKSPACE/packages/yew/src/html/component/properties.rs + | + | Token: AllPropsFor, + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `html::component::properties::__macro::PreBuild::::build` + = note: this error originates in the derive macro `Properties` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0308]: mismatched types - --> tests/derive_props/fail.rs:54:19 + --> tests/derive_props/fail.rs:66:19 | -54 | #[prop_or(123)] +66 | #[prop_or(123)] | ^^^ | | | expected struct `String`, found integer @@ -119,15 +148,15 @@ error[E0308]: mismatched types note: associated function defined here help: try using a conversion method | -54 | #[prop_or(123.to_string())] +66 | #[prop_or(123.to_string())] | ++++++++++++ -54 | #[prop_or(123.to_string())] +66 | #[prop_or(123.to_string())] | ++++++++++++ error[E0277]: expected a `FnOnce<()>` closure, found `{integer}` - --> tests/derive_props/fail.rs:64:24 + --> tests/derive_props/fail.rs:76:24 | -64 | #[prop_or_else(123)] +76 | #[prop_or_else(123)] | ^^^ expected an `FnOnce<()>` closure, found `{integer}` | = help: the trait `FnOnce<()>` is not implemented for `{integer}` @@ -135,20 +164,20 @@ error[E0277]: expected a `FnOnce<()>` closure, found `{integer}` note: required by a bound in `Option::::unwrap_or_else` error[E0593]: function is expected to take 0 arguments, but it takes 1 argument - --> tests/derive_props/fail.rs:84:24 - | -84 | #[prop_or_else(foo)] - | ^^^ expected function that takes 0 arguments + --> tests/derive_props/fail.rs:96:24 + | +96 | #[prop_or_else(foo)] + | ^^^ expected function that takes 0 arguments ... -88 | fn foo(bar: i32) -> String { - | -------------------------- takes 1 argument - | +100 | fn foo(bar: i32) -> String { + | -------------------------- takes 1 argument + | note: required by a bound in `Option::::unwrap_or_else` error[E0271]: type mismatch resolving ` i32 {t10::foo} as FnOnce<()>>::Output == String` - --> tests/derive_props/fail.rs:98:24 - | -98 | #[prop_or_else(foo)] - | ^^^ expected struct `String`, found `i32` - | + --> tests/derive_props/fail.rs:110:24 + | +110 | #[prop_or_else(foo)] + | ^^^ expected struct `String`, found `i32` + | note: required by a bound in `Option::::unwrap_or_else` diff --git a/packages/yew-macro/tests/derive_props/pass.rs b/packages/yew-macro/tests/derive_props/pass.rs index 9bee699e2c0..39086f80581 100644 --- a/packages/yew-macro/tests/derive_props/pass.rs +++ b/packages/yew-macro/tests/derive_props/pass.rs @@ -227,7 +227,7 @@ mod t12 { } fn optional_prop_generics_should_work() { - ::yew::props! { Props::<::std::primitive::bool> { } }; + ::yew::props! { Props::<::std::primitive::bool> { value: ::std::option::Option::Some(true) } }; ::yew::props! { Props::<::std::primitive::bool> { value: true } }; } } @@ -249,7 +249,28 @@ mod raw_field_names { r#true: u32, r#pointless_raw_name: u32, } +} + +mod value_into_some_value_in_props { + #[derive(::std::cmp::PartialEq, ::yew::Properties)] + struct Props { + required: ::std::option::Option, + #[prop_or_default] + optional: ::std::option::Option + } + #[::yew::function_component] + fn Inner(_props: &Props) -> ::yew::html::Html { + ::yew::html!{} + } + + #[::yew::function_component] + fn Main() -> ::yew::html::Html { + ::yew::html! {<> + + + } + } } fn main() {} diff --git a/packages/yew/src/suspense/component.rs b/packages/yew/src/suspense/component.rs index 17c68053fea..80c580f87a3 100644 --- a/packages/yew/src/suspense/component.rs +++ b/packages/yew/src/suspense/component.rs @@ -25,6 +25,7 @@ mod feat_csr_ssr { #[derive(Properties, PartialEq, Debug, Clone)] pub(crate) struct BaseSuspenseProps { pub children: Html, + #[prop_or(None)] pub fallback: Option, } From 7706bcf3a335b62e03166af17d863006831346bc Mon Sep 17 00:00:00 2001 From: Connor King Date: Sat, 23 Sep 2023 08:35:33 -0400 Subject: [PATCH 05/14] Say something about `trunk serve` at the top (#3394) * Say something about `trunk serve` at the top I was following this guide and did `cargo run` instead of `trunk serve` and was very confused * Remove blank line to make Prettier happy --- .../version-0.20/getting-started/build-a-sample-app.mdx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx b/website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx index 996bd3f4a92..b2ff96337a5 100644 --- a/website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx +++ b/website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx @@ -8,12 +8,18 @@ the boilerplate needed for a basic Yew app or manually set up a small project. ## Using a starter template Install [`cargo-generate`](https://github.com/cargo-generate/cargo-generate) by following their installation instructions -then run the following command: +then run the following commands: ```shell cargo generate --git https://github.com/yewstack/yew-trunk-minimal-template ``` +Change directory into your newly created project, then: + +``` +trunk serve +``` + ## Setting up the application manually ### Create Project From 2cbe6cee8ad1df31745494c8f55c146d2300f76d Mon Sep 17 00:00:00 2001 From: Pouriya Date: Sat, 23 Sep 2023 16:08:59 +0330 Subject: [PATCH 06/14] feat: support arrays for Classes/classes!() (#3393) * feat: support arrays for Classes/classes!() * style: update --- packages/yew-macro/tests/classes_macro/classes-pass.rs | 7 ++++++- packages/yew/src/html/classes.rs | 6 ++++++ website/docs/concepts/html/classes.mdx | 4 +--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/yew-macro/tests/classes_macro/classes-pass.rs b/packages/yew-macro/tests/classes_macro/classes-pass.rs index 4735e303d50..fb73e802e1c 100644 --- a/packages/yew-macro/tests/classes_macro/classes-pass.rs +++ b/packages/yew-macro/tests/classes_macro/classes-pass.rs @@ -49,6 +49,11 @@ fn compile_pass() { // single expression ::yew::classes!(::std::vec!["one", "two"]); + // single array + ::yew::classes!(["one", "two"]); + // multiple arrays + ::yew::classes!(["one"], ["two"]); + // optional classes ::yew::classes!( ::std::option::Option::Some("one"), @@ -58,7 +63,7 @@ fn compile_pass() { // mixed types { use ::std::borrow::ToOwned; - ::yew::classes!("one".to_owned(), "two", ::std::vec!["three"]); + ::yew::classes!("one".to_owned(), "two", ::std::vec!["three"], ["four", "five"]); } } diff --git a/packages/yew/src/html/classes.rs b/packages/yew/src/html/classes.rs index f7217278427..0a5bb9cc9b0 100644 --- a/packages/yew/src/html/classes.rs +++ b/packages/yew/src/html/classes.rs @@ -274,6 +274,12 @@ impl + Clone> From<&[T]> for Classes { } } +impl, const SIZE: usize> From<[T; SIZE]> for Classes { + fn from(t: [T; SIZE]) -> Self { + t.into_iter().collect() + } +} + impl PartialEq for Classes { fn eq(&self, other: &Self) -> bool { self.set.len() == other.set.len() && self.set.iter().eq(other.set.iter()) diff --git a/website/docs/concepts/html/classes.mdx b/website/docs/concepts/html/classes.mdx index 5cd87106813..1e6e85d1d53 100644 --- a/website/docs/concepts/html/classes.mdx +++ b/website/docs/concepts/html/classes.mdx @@ -84,10 +84,8 @@ html! { ```rust use yew::{classes, html}; -let my_classes = ["class-1", "class-2"]; - html! { -
+
}; ``` From 954b0ec7b92b2a34b5d45d14e4837d87092e40b7 Mon Sep 17 00:00:00 2001 From: Daniel Sousa Date: Sat, 23 Sep 2023 13:48:22 +0100 Subject: [PATCH 07/14] Correct minor mistakes in website (#3405) * Remove whitespace in website tutorial * Update index.mdx Remove whitespace in tutorial. * Add more information to website. Changes to be committed: modified: website/docs/tutorial/index.mdx modified: website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx modified: website/versioned_docs/version-0.20/tutorial/index.mdx * Remove error: doctest failed, to rerun pass `-p website-test --doc` Changes to be committed: modified: website/docs/migration-guides/yew/from-0_18_0-to-0_19_0.mdx * Correction of minor mistakes in website. Changes to be committed: modified: website/docs/getting-started/build-a-sample-app.mdx modified: website/docs/tutorial/index.mdx modified: website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx modified: website/versioned_docs/version-0.20/tutorial/index.mdx * Run Prettier Changes to be committed: new file: package-lock.json modified: website/docs/tutorial/index.mdx modified: website/package-lock.json modified: website/package.json modified: website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx --- package-lock.json | 6 + .../getting-started/build-a-sample-app.mdx | 16 + website/docs/tutorial/index.mdx | 22 +- website/package-lock.json | 1685 ++--------------- website/package.json | 2 +- .../getting-started/build-a-sample-app.mdx | 21 +- .../version-0.20/tutorial/index.mdx | 18 +- 7 files changed, 227 insertions(+), 1543 deletions(-) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000000..1c67da3f6cc --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "yew", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/website/docs/getting-started/build-a-sample-app.mdx b/website/docs/getting-started/build-a-sample-app.mdx index 2b502a745c4..eab3e9fd750 100644 --- a/website/docs/getting-started/build-a-sample-app.mdx +++ b/website/docs/getting-started/build-a-sample-app.mdx @@ -132,7 +132,23 @@ Run the following command to build and serve the application locally. trunk serve ``` +:::info +Add option '--open' to open your default browser `trunk serve --open`. +::: + Trunk will rebuild your application if you modify any of its source code files. +By default server will listening at address '127.0.0.1' and port '8080' => [http://localhost:8080](http://127.0.0.1:8080). +To change it, create the following file and edit as needed: + +```toml title="Trunk.toml" +[serve] +# The address to serve on LAN. +address = "127.0.0.1" +# The address to serve on WAN. +# address = "0.0.0.0" +# The port to serve on. +port = 8000 +``` ## Congratulations diff --git a/website/docs/tutorial/index.mdx b/website/docs/tutorial/index.mdx index 9bf1c2c34bd..9599ff76316 100644 --- a/website/docs/tutorial/index.mdx +++ b/website/docs/tutorial/index.mdx @@ -120,9 +120,27 @@ Run the following command to build and serve the application locally. trunk serve --open ``` +:::info +Remove option '--open' to not open your default browser `trunk serve`. +::: + Trunk will open your application in your default browser, watch the project directory and helpfully rebuild your -application if you modify any source files. If you are curious, you can run `trunk help` and `trunk help ` -for more details on what is happening. +application if you modify any source files. +This will fail if the socket is being used by another application. +By default server will listening at address '127.0.0.1' and port '8080' => [http://localhost:8080](http://127.0.0.1:8080). +To change it, create the following file and edit as needed: + +```toml title="Trunk.toml" +[serve] +# The address to serve on LAN. +address = "127.0.0.1" +# The address to serve on WAN. +# address = "0.0.0.0" +# The port to serve on. +port = 8000 +``` + +If you are curious, you can run `trunk help` and `trunk help ` for more details on what is happening. ### Congratulations diff --git a/website/package-lock.json b/website/package-lock.json index 6e921238a0d..fafb0e51a4d 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -34,7 +34,7 @@ "@typescript-eslint/eslint-plugin": "^5.57.0", "@typescript-eslint/parser": "^5.54.0", "dir-compare": "^4.0.0", - "prettier": "2.8.8", + "prettier": "^2.8.8", "typescript": "^4.8.3" } }, @@ -1851,9 +1851,9 @@ } }, "node_modules/@docusaurus/core": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.0.tgz", - "integrity": "sha512-J55/WEoIpRcLf3afO5POHPguVZosKmJEQWKBL+K7TAnfuE7i+Y0NPLlkKtnWCehagGsgTqClfQEexH/UT4kELA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.1.tgz", + "integrity": "sha512-SNsY7PshK3Ri7vtsLXVeAJGS50nJN3RgF836zkyUfAD01Fq+sAk5EwWgLw+nnm5KVNGDu7PRR2kRGDsWvqpo0g==", "dependencies": { "@babel/core": "^7.18.6", "@babel/generator": "^7.18.7", @@ -1865,13 +1865,13 @@ "@babel/runtime": "^7.18.6", "@babel/runtime-corejs3": "^7.18.6", "@babel/traverse": "^7.18.8", - "@docusaurus/cssnano-preset": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/mdx-loader": "2.4.0", + "@docusaurus/cssnano-preset": "2.4.1", + "@docusaurus/logger": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-common": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "@slorber/static-site-generator-webpack-plugin": "^4.0.7", "@svgr/webpack": "^6.2.1", "autoprefixer": "^10.4.7", @@ -2167,9 +2167,9 @@ } }, "node_modules/@docusaurus/cssnano-preset": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.0.tgz", - "integrity": "sha512-RmdiA3IpsLgZGXRzqnmTbGv43W4OD44PCo+6Q/aYjEM2V57vKCVqNzuafE94jv0z/PjHoXUrjr69SaRymBKYYw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.1.tgz", + "integrity": "sha512-ka+vqXwtcW1NbXxWsh6yA1Ckii1klY9E53cJ4O9J09nkMBgrNX3iEFED1fWdv8wf4mJjvGi5RLZ2p9hJNjsLyQ==", "dependencies": { "cssnano-preset-advanced": "^5.3.8", "postcss": "^8.4.14", @@ -2181,9 +2181,9 @@ } }, "node_modules/@docusaurus/logger": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.0.tgz", - "integrity": "sha512-T8+qR4APN+MjcC9yL2Es+xPJ2923S9hpzDmMtdsOcUGLqpCGBbU1vp3AAqDwXtVgFkq+NsEk7sHdVsfLWR/AXw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.1.tgz", + "integrity": "sha512-5h5ysIIWYIDHyTVd8BjheZmQZmEgWDR54aQ1BX9pjFfpyzFo5puKXKYrYJXbjEHGyVhEzmB9UXwbxGfaZhOjcg==", "dependencies": { "chalk": "^4.1.2", "tslib": "^2.4.0" @@ -2193,14 +2193,14 @@ } }, "node_modules/@docusaurus/mdx-loader": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.0.tgz", - "integrity": "sha512-GWoH4izZKOmFoC+gbI2/y8deH/xKLvzz/T5BsEexBye8EHQlwsA7FMrVa48N063bJBH4FUOiRRXxk5rq9cC36g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.1.tgz", + "integrity": "sha512-4KhUhEavteIAmbBj7LVFnrVYDiU51H5YWW1zY6SmBSte/YLhDutztLTBE0PQl1Grux1jzUJeaSvAzHpTn6JJDQ==", "dependencies": { "@babel/parser": "^7.18.8", "@babel/traverse": "^7.18.8", - "@docusaurus/logger": "2.4.0", - "@docusaurus/utils": "2.4.0", + "@docusaurus/logger": "2.4.1", + "@docusaurus/utils": "2.4.1", "@mdx-js/mdx": "^1.6.22", "escape-html": "^1.0.3", "file-loader": "^6.2.0", @@ -2243,1394 +2243,48 @@ } }, "node_modules/@docusaurus/plugin-client-redirects": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-2.4.0.tgz", - "integrity": "sha512-HsS+Dc2ZLWhfpjYJ5LIrOB/XfXZcElcC7o1iA4yIVtiFz+LHhwP863fhqbwSJ1c6tNDOYBH3HwbskHrc/PIn7Q==", - "dependencies": { - "@docusaurus/core": "2.4.0", - "@docusaurus/logger": "2.4.0", - "@docusaurus/utils": "2.4.0", - "@docusaurus/utils-common": "2.4.0", - "@docusaurus/utils-validation": "2.4.0", - "eta": "^2.0.0", - "fs-extra": "^10.1.0", - "lodash": "^4.17.21", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-blog": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.4.1.tgz", - "integrity": "sha512-E2i7Knz5YIbE1XELI6RlTnZnGgS52cUO4BlCiCUCvQHbR+s1xeIWz4C6BtaVnlug0Ccz7nFSksfwDpVlkujg5Q==", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-2.4.1.tgz", + "integrity": "sha512-tp0j16gaLIJ4p+IR0P6KDOFsTOGGMY54MNPnmM61Vaqqt5omLqsuKUO8UlCGU1oW/4EIQOhXYy99XYY5MjE+7A==", "dependencies": { "@docusaurus/core": "2.4.1", "@docusaurus/logger": "2.4.1", - "@docusaurus/mdx-loader": "2.4.1", - "@docusaurus/types": "2.4.1", - "@docusaurus/utils": "2.4.1", - "@docusaurus/utils-common": "2.4.1", - "@docusaurus/utils-validation": "2.4.1", - "cheerio": "^1.0.0-rc.12", - "feed": "^4.2.2", - "fs-extra": "^10.1.0", - "lodash": "^4.17.21", - "reading-time": "^1.5.0", - "tslib": "^2.4.0", - "unist-util-visit": "^2.0.3", - "utility-types": "^3.10.0", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/@docusaurus/core": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.1.tgz", - "integrity": "sha512-SNsY7PshK3Ri7vtsLXVeAJGS50nJN3RgF836zkyUfAD01Fq+sAk5EwWgLw+nnm5KVNGDu7PRR2kRGDsWvqpo0g==", - "dependencies": { - "@babel/core": "^7.18.6", - "@babel/generator": "^7.18.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.18.6", - "@babel/preset-env": "^7.18.6", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@babel/runtime": "^7.18.6", - "@babel/runtime-corejs3": "^7.18.6", - "@babel/traverse": "^7.18.8", - "@docusaurus/cssnano-preset": "2.4.1", - "@docusaurus/logger": "2.4.1", - "@docusaurus/mdx-loader": "2.4.1", - "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "2.4.1", - "@docusaurus/utils-common": "2.4.1", - "@docusaurus/utils-validation": "2.4.1", - "@slorber/static-site-generator-webpack-plugin": "^4.0.7", - "@svgr/webpack": "^6.2.1", - "autoprefixer": "^10.4.7", - "babel-loader": "^8.2.5", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.0", - "cli-table3": "^0.6.2", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.23.3", - "css-loader": "^6.7.1", - "css-minimizer-webpack-plugin": "^4.0.0", - "cssnano": "^5.1.12", - "del": "^6.1.1", - "detect-port": "^1.3.0", - "escape-html": "^1.0.3", - "eta": "^2.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "html-minifier-terser": "^6.1.0", - "html-tags": "^3.2.0", - "html-webpack-plugin": "^5.5.0", - "import-fresh": "^3.3.0", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.6.1", - "postcss": "^8.4.14", - "postcss-loader": "^7.0.0", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@5.5.2", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.3", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.3", - "rtl-detect": "^1.0.4", - "semver": "^7.3.7", - "serve-handler": "^6.1.3", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.3", - "tslib": "^2.4.0", - "update-notifier": "^5.1.0", - "url-loader": "^4.1.1", - "wait-on": "^6.0.1", - "webpack": "^5.73.0", - "webpack-bundle-analyzer": "^4.5.0", - "webpack-dev-server": "^4.9.3", - "webpack-merge": "^5.8.0", - "webpackbar": "^5.0.2" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/@docusaurus/cssnano-preset": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.1.tgz", - "integrity": "sha512-ka+vqXwtcW1NbXxWsh6yA1Ckii1klY9E53cJ4O9J09nkMBgrNX3iEFED1fWdv8wf4mJjvGi5RLZ2p9hJNjsLyQ==", - "dependencies": { - "cssnano-preset-advanced": "^5.3.8", - "postcss": "^8.4.14", - "postcss-sort-media-queries": "^4.2.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/@docusaurus/logger": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.1.tgz", - "integrity": "sha512-5h5ysIIWYIDHyTVd8BjheZmQZmEgWDR54aQ1BX9pjFfpyzFo5puKXKYrYJXbjEHGyVhEzmB9UXwbxGfaZhOjcg==", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/@docusaurus/mdx-loader": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.1.tgz", - "integrity": "sha512-4KhUhEavteIAmbBj7LVFnrVYDiU51H5YWW1zY6SmBSte/YLhDutztLTBE0PQl1Grux1jzUJeaSvAzHpTn6JJDQ==", - "dependencies": { - "@babel/parser": "^7.18.8", - "@babel/traverse": "^7.18.8", - "@docusaurus/logger": "2.4.1", "@docusaurus/utils": "2.4.1", - "@mdx-js/mdx": "^1.6.22", - "escape-html": "^1.0.3", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "image-size": "^1.0.1", - "mdast-util-to-string": "^2.0.0", - "remark-emoji": "^2.2.0", - "stringify-object": "^3.3.0", - "tslib": "^2.4.0", - "unified": "^9.2.2", - "unist-util-visit": "^2.0.3", - "url-loader": "^4.1.1", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/@docusaurus/utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.1.tgz", - "integrity": "sha512-1lvEZdAQhKNht9aPXPoh69eeKnV0/62ROhQeFKKxmzd0zkcuE/Oc5Gpnt00y/f5bIsmOsYMY7Pqfm/5rteT5GA==", - "dependencies": { - "@docusaurus/logger": "2.4.1", - "@svgr/webpack": "^6.2.1", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "github-slugger": "^1.4.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.4.0", - "url-loader": "^4.1.1", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/@docusaurus/utils-common": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.1.tgz", - "integrity": "sha512-bCVGdZU+z/qVcIiEQdyx0K13OC5mYwxhSuDUR95oFbKVuXYRrTVrwZIqQljuo1fyJvFTKHiL9L9skQOPokuFNQ==", - "dependencies": { - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/@docusaurus/utils-validation": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.1.tgz", - "integrity": "sha512-unII3hlJlDwZ3w8U+pMO3Lx3RhI4YEbY3YNsQj4yzrkZzlpqZOLuAiZK2JyULnD+TKbceKU0WyWkQXtYbLNDFA==", - "dependencies": { - "@docusaurus/logger": "2.4.1", - "@docusaurus/utils": "2.4.1", - "joi": "^17.6.0", - "js-yaml": "^4.1.0", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-content-docs": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.4.1.tgz", - "integrity": "sha512-Lo7lSIcpswa2Kv4HEeUcGYqaasMUQNpjTXpV0N8G6jXgZaQurqp7E8NGYeGbDXnb48czmHWbzDL4S3+BbK0VzA==", - "dependencies": { - "@docusaurus/core": "2.4.1", - "@docusaurus/logger": "2.4.1", - "@docusaurus/mdx-loader": "2.4.1", - "@docusaurus/module-type-aliases": "2.4.1", - "@docusaurus/types": "2.4.1", - "@docusaurus/utils": "2.4.1", - "@docusaurus/utils-validation": "2.4.1", - "@types/react-router-config": "^5.0.6", - "combine-promises": "^1.1.0", - "fs-extra": "^10.1.0", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.4.0", - "utility-types": "^3.10.0", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/core": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.1.tgz", - "integrity": "sha512-SNsY7PshK3Ri7vtsLXVeAJGS50nJN3RgF836zkyUfAD01Fq+sAk5EwWgLw+nnm5KVNGDu7PRR2kRGDsWvqpo0g==", - "dependencies": { - "@babel/core": "^7.18.6", - "@babel/generator": "^7.18.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.18.6", - "@babel/preset-env": "^7.18.6", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@babel/runtime": "^7.18.6", - "@babel/runtime-corejs3": "^7.18.6", - "@babel/traverse": "^7.18.8", - "@docusaurus/cssnano-preset": "2.4.1", - "@docusaurus/logger": "2.4.1", - "@docusaurus/mdx-loader": "2.4.1", - "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "2.4.1", - "@docusaurus/utils-common": "2.4.1", - "@docusaurus/utils-validation": "2.4.1", - "@slorber/static-site-generator-webpack-plugin": "^4.0.7", - "@svgr/webpack": "^6.2.1", - "autoprefixer": "^10.4.7", - "babel-loader": "^8.2.5", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.0", - "cli-table3": "^0.6.2", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.23.3", - "css-loader": "^6.7.1", - "css-minimizer-webpack-plugin": "^4.0.0", - "cssnano": "^5.1.12", - "del": "^6.1.1", - "detect-port": "^1.3.0", - "escape-html": "^1.0.3", - "eta": "^2.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "html-minifier-terser": "^6.1.0", - "html-tags": "^3.2.0", - "html-webpack-plugin": "^5.5.0", - "import-fresh": "^3.3.0", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.6.1", - "postcss": "^8.4.14", - "postcss-loader": "^7.0.0", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@5.5.2", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.3", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.3", - "rtl-detect": "^1.0.4", - "semver": "^7.3.7", - "serve-handler": "^6.1.3", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.3", - "tslib": "^2.4.0", - "update-notifier": "^5.1.0", - "url-loader": "^4.1.1", - "wait-on": "^6.0.1", - "webpack": "^5.73.0", - "webpack-bundle-analyzer": "^4.5.0", - "webpack-dev-server": "^4.9.3", - "webpack-merge": "^5.8.0", - "webpackbar": "^5.0.2" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/cssnano-preset": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.1.tgz", - "integrity": "sha512-ka+vqXwtcW1NbXxWsh6yA1Ckii1klY9E53cJ4O9J09nkMBgrNX3iEFED1fWdv8wf4mJjvGi5RLZ2p9hJNjsLyQ==", - "dependencies": { - "cssnano-preset-advanced": "^5.3.8", - "postcss": "^8.4.14", - "postcss-sort-media-queries": "^4.2.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/logger": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.1.tgz", - "integrity": "sha512-5h5ysIIWYIDHyTVd8BjheZmQZmEgWDR54aQ1BX9pjFfpyzFo5puKXKYrYJXbjEHGyVhEzmB9UXwbxGfaZhOjcg==", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/mdx-loader": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.1.tgz", - "integrity": "sha512-4KhUhEavteIAmbBj7LVFnrVYDiU51H5YWW1zY6SmBSte/YLhDutztLTBE0PQl1Grux1jzUJeaSvAzHpTn6JJDQ==", - "dependencies": { - "@babel/parser": "^7.18.8", - "@babel/traverse": "^7.18.8", - "@docusaurus/logger": "2.4.1", - "@docusaurus/utils": "2.4.1", - "@mdx-js/mdx": "^1.6.22", - "escape-html": "^1.0.3", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "image-size": "^1.0.1", - "mdast-util-to-string": "^2.0.0", - "remark-emoji": "^2.2.0", - "stringify-object": "^3.3.0", - "tslib": "^2.4.0", - "unified": "^9.2.2", - "unist-util-visit": "^2.0.3", - "url-loader": "^4.1.1", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.1.tgz", - "integrity": "sha512-1lvEZdAQhKNht9aPXPoh69eeKnV0/62ROhQeFKKxmzd0zkcuE/Oc5Gpnt00y/f5bIsmOsYMY7Pqfm/5rteT5GA==", - "dependencies": { - "@docusaurus/logger": "2.4.1", - "@svgr/webpack": "^6.2.1", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "github-slugger": "^1.4.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.4.0", - "url-loader": "^4.1.1", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/utils-common": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.1.tgz", - "integrity": "sha512-bCVGdZU+z/qVcIiEQdyx0K13OC5mYwxhSuDUR95oFbKVuXYRrTVrwZIqQljuo1fyJvFTKHiL9L9skQOPokuFNQ==", - "dependencies": { - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/utils-validation": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.1.tgz", - "integrity": "sha512-unII3hlJlDwZ3w8U+pMO3Lx3RhI4YEbY3YNsQj4yzrkZzlpqZOLuAiZK2JyULnD+TKbceKU0WyWkQXtYbLNDFA==", - "dependencies": { - "@docusaurus/logger": "2.4.1", - "@docusaurus/utils": "2.4.1", - "joi": "^17.6.0", - "js-yaml": "^4.1.0", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-content-pages": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.4.1.tgz", - "integrity": "sha512-/UjuH/76KLaUlL+o1OvyORynv6FURzjurSjvn2lbWTFc4tpYY2qLYTlKpTCBVPhlLUQsfyFnshEJDLmPneq2oA==", - "dependencies": { - "@docusaurus/core": "2.4.1", - "@docusaurus/mdx-loader": "2.4.1", - "@docusaurus/types": "2.4.1", - "@docusaurus/utils": "2.4.1", - "@docusaurus/utils-validation": "2.4.1", - "fs-extra": "^10.1.0", - "tslib": "^2.4.0", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/@docusaurus/core": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.1.tgz", - "integrity": "sha512-SNsY7PshK3Ri7vtsLXVeAJGS50nJN3RgF836zkyUfAD01Fq+sAk5EwWgLw+nnm5KVNGDu7PRR2kRGDsWvqpo0g==", - "dependencies": { - "@babel/core": "^7.18.6", - "@babel/generator": "^7.18.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.18.6", - "@babel/preset-env": "^7.18.6", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@babel/runtime": "^7.18.6", - "@babel/runtime-corejs3": "^7.18.6", - "@babel/traverse": "^7.18.8", - "@docusaurus/cssnano-preset": "2.4.1", - "@docusaurus/logger": "2.4.1", - "@docusaurus/mdx-loader": "2.4.1", - "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "2.4.1", - "@docusaurus/utils-common": "2.4.1", - "@docusaurus/utils-validation": "2.4.1", - "@slorber/static-site-generator-webpack-plugin": "^4.0.7", - "@svgr/webpack": "^6.2.1", - "autoprefixer": "^10.4.7", - "babel-loader": "^8.2.5", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.0", - "cli-table3": "^0.6.2", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.23.3", - "css-loader": "^6.7.1", - "css-minimizer-webpack-plugin": "^4.0.0", - "cssnano": "^5.1.12", - "del": "^6.1.1", - "detect-port": "^1.3.0", - "escape-html": "^1.0.3", - "eta": "^2.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "html-minifier-terser": "^6.1.0", - "html-tags": "^3.2.0", - "html-webpack-plugin": "^5.5.0", - "import-fresh": "^3.3.0", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.6.1", - "postcss": "^8.4.14", - "postcss-loader": "^7.0.0", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@5.5.2", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.3", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.3", - "rtl-detect": "^1.0.4", - "semver": "^7.3.7", - "serve-handler": "^6.1.3", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.3", - "tslib": "^2.4.0", - "update-notifier": "^5.1.0", - "url-loader": "^4.1.1", - "wait-on": "^6.0.1", - "webpack": "^5.73.0", - "webpack-bundle-analyzer": "^4.5.0", - "webpack-dev-server": "^4.9.3", - "webpack-merge": "^5.8.0", - "webpackbar": "^5.0.2" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/@docusaurus/cssnano-preset": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.1.tgz", - "integrity": "sha512-ka+vqXwtcW1NbXxWsh6yA1Ckii1klY9E53cJ4O9J09nkMBgrNX3iEFED1fWdv8wf4mJjvGi5RLZ2p9hJNjsLyQ==", - "dependencies": { - "cssnano-preset-advanced": "^5.3.8", - "postcss": "^8.4.14", - "postcss-sort-media-queries": "^4.2.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/@docusaurus/logger": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.1.tgz", - "integrity": "sha512-5h5ysIIWYIDHyTVd8BjheZmQZmEgWDR54aQ1BX9pjFfpyzFo5puKXKYrYJXbjEHGyVhEzmB9UXwbxGfaZhOjcg==", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/@docusaurus/mdx-loader": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.1.tgz", - "integrity": "sha512-4KhUhEavteIAmbBj7LVFnrVYDiU51H5YWW1zY6SmBSte/YLhDutztLTBE0PQl1Grux1jzUJeaSvAzHpTn6JJDQ==", - "dependencies": { - "@babel/parser": "^7.18.8", - "@babel/traverse": "^7.18.8", - "@docusaurus/logger": "2.4.1", - "@docusaurus/utils": "2.4.1", - "@mdx-js/mdx": "^1.6.22", - "escape-html": "^1.0.3", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "image-size": "^1.0.1", - "mdast-util-to-string": "^2.0.0", - "remark-emoji": "^2.2.0", - "stringify-object": "^3.3.0", - "tslib": "^2.4.0", - "unified": "^9.2.2", - "unist-util-visit": "^2.0.3", - "url-loader": "^4.1.1", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/@docusaurus/utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.1.tgz", - "integrity": "sha512-1lvEZdAQhKNht9aPXPoh69eeKnV0/62ROhQeFKKxmzd0zkcuE/Oc5Gpnt00y/f5bIsmOsYMY7Pqfm/5rteT5GA==", - "dependencies": { - "@docusaurus/logger": "2.4.1", - "@svgr/webpack": "^6.2.1", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "github-slugger": "^1.4.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.4.0", - "url-loader": "^4.1.1", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/@docusaurus/utils-common": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.1.tgz", - "integrity": "sha512-bCVGdZU+z/qVcIiEQdyx0K13OC5mYwxhSuDUR95oFbKVuXYRrTVrwZIqQljuo1fyJvFTKHiL9L9skQOPokuFNQ==", - "dependencies": { - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/@docusaurus/utils-validation": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.1.tgz", - "integrity": "sha512-unII3hlJlDwZ3w8U+pMO3Lx3RhI4YEbY3YNsQj4yzrkZzlpqZOLuAiZK2JyULnD+TKbceKU0WyWkQXtYbLNDFA==", - "dependencies": { - "@docusaurus/logger": "2.4.1", - "@docusaurus/utils": "2.4.1", - "joi": "^17.6.0", - "js-yaml": "^4.1.0", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-google-analytics": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.4.1.tgz", - "integrity": "sha512-dyZJdJiCoL+rcfnm0RPkLt/o732HvLiEwmtoNzOoz9MSZz117UH2J6U2vUDtzUzwtFLIf32KkeyzisbwUCgcaQ==", - "dependencies": { - "@docusaurus/core": "2.4.1", - "@docusaurus/types": "2.4.1", - "@docusaurus/utils-validation": "2.4.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@docusaurus/core": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.1.tgz", - "integrity": "sha512-SNsY7PshK3Ri7vtsLXVeAJGS50nJN3RgF836zkyUfAD01Fq+sAk5EwWgLw+nnm5KVNGDu7PRR2kRGDsWvqpo0g==", - "dependencies": { - "@babel/core": "^7.18.6", - "@babel/generator": "^7.18.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.18.6", - "@babel/preset-env": "^7.18.6", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@babel/runtime": "^7.18.6", - "@babel/runtime-corejs3": "^7.18.6", - "@babel/traverse": "^7.18.8", - "@docusaurus/cssnano-preset": "2.4.1", - "@docusaurus/logger": "2.4.1", - "@docusaurus/mdx-loader": "2.4.1", - "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "2.4.1", - "@docusaurus/utils-common": "2.4.1", - "@docusaurus/utils-validation": "2.4.1", - "@slorber/static-site-generator-webpack-plugin": "^4.0.7", - "@svgr/webpack": "^6.2.1", - "autoprefixer": "^10.4.7", - "babel-loader": "^8.2.5", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.0", - "cli-table3": "^0.6.2", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.23.3", - "css-loader": "^6.7.1", - "css-minimizer-webpack-plugin": "^4.0.0", - "cssnano": "^5.1.12", - "del": "^6.1.1", - "detect-port": "^1.3.0", - "escape-html": "^1.0.3", - "eta": "^2.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "html-minifier-terser": "^6.1.0", - "html-tags": "^3.2.0", - "html-webpack-plugin": "^5.5.0", - "import-fresh": "^3.3.0", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.6.1", - "postcss": "^8.4.14", - "postcss-loader": "^7.0.0", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@5.5.2", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.3", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.3", - "rtl-detect": "^1.0.4", - "semver": "^7.3.7", - "serve-handler": "^6.1.3", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.3", - "tslib": "^2.4.0", - "update-notifier": "^5.1.0", - "url-loader": "^4.1.1", - "wait-on": "^6.0.1", - "webpack": "^5.73.0", - "webpack-bundle-analyzer": "^4.5.0", - "webpack-dev-server": "^4.9.3", - "webpack-merge": "^5.8.0", - "webpackbar": "^5.0.2" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@docusaurus/cssnano-preset": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.1.tgz", - "integrity": "sha512-ka+vqXwtcW1NbXxWsh6yA1Ckii1klY9E53cJ4O9J09nkMBgrNX3iEFED1fWdv8wf4mJjvGi5RLZ2p9hJNjsLyQ==", - "dependencies": { - "cssnano-preset-advanced": "^5.3.8", - "postcss": "^8.4.14", - "postcss-sort-media-queries": "^4.2.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@docusaurus/logger": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.1.tgz", - "integrity": "sha512-5h5ysIIWYIDHyTVd8BjheZmQZmEgWDR54aQ1BX9pjFfpyzFo5puKXKYrYJXbjEHGyVhEzmB9UXwbxGfaZhOjcg==", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@docusaurus/mdx-loader": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.1.tgz", - "integrity": "sha512-4KhUhEavteIAmbBj7LVFnrVYDiU51H5YWW1zY6SmBSte/YLhDutztLTBE0PQl1Grux1jzUJeaSvAzHpTn6JJDQ==", - "dependencies": { - "@babel/parser": "^7.18.8", - "@babel/traverse": "^7.18.8", - "@docusaurus/logger": "2.4.1", - "@docusaurus/utils": "2.4.1", - "@mdx-js/mdx": "^1.6.22", - "escape-html": "^1.0.3", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "image-size": "^1.0.1", - "mdast-util-to-string": "^2.0.0", - "remark-emoji": "^2.2.0", - "stringify-object": "^3.3.0", - "tslib": "^2.4.0", - "unified": "^9.2.2", - "unist-util-visit": "^2.0.3", - "url-loader": "^4.1.1", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@docusaurus/utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.1.tgz", - "integrity": "sha512-1lvEZdAQhKNht9aPXPoh69eeKnV0/62ROhQeFKKxmzd0zkcuE/Oc5Gpnt00y/f5bIsmOsYMY7Pqfm/5rteT5GA==", - "dependencies": { - "@docusaurus/logger": "2.4.1", - "@svgr/webpack": "^6.2.1", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "github-slugger": "^1.4.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.4.0", - "url-loader": "^4.1.1", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@docusaurus/utils-common": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.1.tgz", - "integrity": "sha512-bCVGdZU+z/qVcIiEQdyx0K13OC5mYwxhSuDUR95oFbKVuXYRrTVrwZIqQljuo1fyJvFTKHiL9L9skQOPokuFNQ==", - "dependencies": { - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@docusaurus/utils-validation": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.1.tgz", - "integrity": "sha512-unII3hlJlDwZ3w8U+pMO3Lx3RhI4YEbY3YNsQj4yzrkZzlpqZOLuAiZK2JyULnD+TKbceKU0WyWkQXtYbLNDFA==", - "dependencies": { - "@docusaurus/logger": "2.4.1", - "@docusaurus/utils": "2.4.1", - "joi": "^17.6.0", - "js-yaml": "^4.1.0", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", - "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", - "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", - "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", - "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", - "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", - "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/babel-preset": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.5.1.tgz", - "integrity": "sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "^6.5.1", - "@svgr/babel-plugin-remove-jsx-attribute": "*", - "@svgr/babel-plugin-remove-jsx-empty-expression": "*", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^6.5.1", - "@svgr/babel-plugin-svg-dynamic-title": "^6.5.1", - "@svgr/babel-plugin-svg-em-dimensions": "^6.5.1", - "@svgr/babel-plugin-transform-react-native-svg": "^6.5.1", - "@svgr/babel-plugin-transform-svg-component": "^6.5.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/core": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-6.5.1.tgz", - "integrity": "sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==", - "dependencies": { - "@babel/core": "^7.19.6", - "@svgr/babel-preset": "^6.5.1", - "@svgr/plugin-jsx": "^6.5.1", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/hast-util-to-babel-ast": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", - "integrity": "sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==", - "dependencies": { - "@babel/types": "^7.20.0", - "entities": "^4.4.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/plugin-jsx": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", - "integrity": "sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==", - "dependencies": { - "@babel/core": "^7.19.6", - "@svgr/babel-preset": "^6.5.1", - "@svgr/hast-util-to-babel-ast": "^6.5.1", - "svg-parser": "^2.0.4" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "^6.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/plugin-svgo": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz", - "integrity": "sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==", - "dependencies": { - "cosmiconfig": "^7.0.1", - "deepmerge": "^4.2.2", - "svgo": "^2.8.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@svgr/webpack": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.5.1.tgz", - "integrity": "sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==", - "dependencies": { - "@babel/core": "^7.19.6", - "@babel/plugin-transform-react-constant-elements": "^7.18.12", - "@babel/preset-env": "^7.19.4", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@svgr/core": "^6.5.1", - "@svgr/plugin-jsx": "^6.5.1", - "@svgr/plugin-svgo": "^6.5.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@docusaurus/react-loadable": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", - "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", - "dependencies": { - "@types/react": "*", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": "*" - } - }, - "node_modules/@docusaurus/theme-classic": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-2.4.1.tgz", - "integrity": "sha512-Rz0wKUa+LTW1PLXmwnf8mn85EBzaGSt6qamqtmnh9Hflkc+EqiYMhtUJeLdV+wsgYq4aG0ANc+bpUDpsUhdnwg==", - "dependencies": { - "@docusaurus/core": "2.4.1", - "@docusaurus/mdx-loader": "2.4.1", - "@docusaurus/module-type-aliases": "2.4.1", - "@docusaurus/plugin-content-blog": "2.4.1", - "@docusaurus/plugin-content-docs": "2.4.1", - "@docusaurus/plugin-content-pages": "2.4.1", - "@docusaurus/theme-common": "2.4.1", - "@docusaurus/theme-translations": "2.4.1", - "@docusaurus/types": "2.4.1", - "@docusaurus/utils": "2.4.1", - "@docusaurus/utils-common": "2.4.1", - "@docusaurus/utils-validation": "2.4.1", - "@mdx-js/react": "^1.6.22", - "clsx": "^1.2.1", - "copy-text-to-clipboard": "^3.0.1", - "infima": "0.2.0-alpha.43", - "lodash": "^4.17.21", - "nprogress": "^0.2.0", - "postcss": "^8.4.14", - "prism-react-renderer": "^1.3.5", - "prismjs": "^1.28.0", - "react-router-dom": "^5.3.3", - "rtlcss": "^3.5.0", - "tslib": "^2.4.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/core": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.1.tgz", - "integrity": "sha512-SNsY7PshK3Ri7vtsLXVeAJGS50nJN3RgF836zkyUfAD01Fq+sAk5EwWgLw+nnm5KVNGDu7PRR2kRGDsWvqpo0g==", - "dependencies": { - "@babel/core": "^7.18.6", - "@babel/generator": "^7.18.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.18.6", - "@babel/preset-env": "^7.18.6", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@babel/runtime": "^7.18.6", - "@babel/runtime-corejs3": "^7.18.6", - "@babel/traverse": "^7.18.8", - "@docusaurus/cssnano-preset": "2.4.1", - "@docusaurus/logger": "2.4.1", - "@docusaurus/mdx-loader": "2.4.1", - "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "2.4.1", - "@docusaurus/utils-common": "2.4.1", - "@docusaurus/utils-validation": "2.4.1", - "@slorber/static-site-generator-webpack-plugin": "^4.0.7", - "@svgr/webpack": "^6.2.1", - "autoprefixer": "^10.4.7", - "babel-loader": "^8.2.5", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.0", - "cli-table3": "^0.6.2", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.23.3", - "css-loader": "^6.7.1", - "css-minimizer-webpack-plugin": "^4.0.0", - "cssnano": "^5.1.12", - "del": "^6.1.1", - "detect-port": "^1.3.0", - "escape-html": "^1.0.3", - "eta": "^2.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "html-minifier-terser": "^6.1.0", - "html-tags": "^3.2.0", - "html-webpack-plugin": "^5.5.0", - "import-fresh": "^3.3.0", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.6.1", - "postcss": "^8.4.14", - "postcss-loader": "^7.0.0", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@5.5.2", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.3", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.3", - "rtl-detect": "^1.0.4", - "semver": "^7.3.7", - "serve-handler": "^6.1.3", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.3", - "tslib": "^2.4.0", - "update-notifier": "^5.1.0", - "url-loader": "^4.1.1", - "wait-on": "^6.0.1", - "webpack": "^5.73.0", - "webpack-bundle-analyzer": "^4.5.0", - "webpack-dev-server": "^4.9.3", - "webpack-merge": "^5.8.0", - "webpackbar": "^5.0.2" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/cssnano-preset": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.1.tgz", - "integrity": "sha512-ka+vqXwtcW1NbXxWsh6yA1Ckii1klY9E53cJ4O9J09nkMBgrNX3iEFED1fWdv8wf4mJjvGi5RLZ2p9hJNjsLyQ==", - "dependencies": { - "cssnano-preset-advanced": "^5.3.8", - "postcss": "^8.4.14", - "postcss-sort-media-queries": "^4.2.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/logger": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.1.tgz", - "integrity": "sha512-5h5ysIIWYIDHyTVd8BjheZmQZmEgWDR54aQ1BX9pjFfpyzFo5puKXKYrYJXbjEHGyVhEzmB9UXwbxGfaZhOjcg==", - "dependencies": { - "chalk": "^4.1.2", + "@docusaurus/utils-common": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", + "eta": "^2.0.0", + "fs-extra": "^10.1.0", + "lodash": "^4.17.21", "tslib": "^2.4.0" }, "engines": { "node": ">=16.14" + }, + "peerDependencies": { + "react": "^16.8.4 || ^17.0.0", + "react-dom": "^16.8.4 || ^17.0.0" } }, - "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/mdx-loader": { + "node_modules/@docusaurus/plugin-content-blog": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.1.tgz", - "integrity": "sha512-4KhUhEavteIAmbBj7LVFnrVYDiU51H5YWW1zY6SmBSte/YLhDutztLTBE0PQl1Grux1jzUJeaSvAzHpTn6JJDQ==", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.4.1.tgz", + "integrity": "sha512-E2i7Knz5YIbE1XELI6RlTnZnGgS52cUO4BlCiCUCvQHbR+s1xeIWz4C6BtaVnlug0Ccz7nFSksfwDpVlkujg5Q==", "dependencies": { - "@babel/parser": "^7.18.8", - "@babel/traverse": "^7.18.8", + "@docusaurus/core": "2.4.1", "@docusaurus/logger": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/types": "2.4.1", "@docusaurus/utils": "2.4.1", - "@mdx-js/mdx": "^1.6.22", - "escape-html": "^1.0.3", - "file-loader": "^6.2.0", + "@docusaurus/utils-common": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", + "cheerio": "^1.0.0-rc.12", + "feed": "^4.2.2", "fs-extra": "^10.1.0", - "image-size": "^1.0.1", - "mdast-util-to-string": "^2.0.0", - "remark-emoji": "^2.2.0", - "stringify-object": "^3.3.0", + "lodash": "^4.17.21", + "reading-time": "^1.5.0", "tslib": "^2.4.0", - "unified": "^9.2.2", "unist-util-visit": "^2.0.3", - "url-loader": "^4.1.1", + "utility-types": "^3.10.0", "webpack": "^5.73.0" }, "engines": { @@ -3641,94 +2295,117 @@ "react-dom": "^16.8.4 || ^17.0.0" } }, - "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/utils": { + "node_modules/@docusaurus/plugin-content-docs": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.1.tgz", - "integrity": "sha512-1lvEZdAQhKNht9aPXPoh69eeKnV0/62ROhQeFKKxmzd0zkcuE/Oc5Gpnt00y/f5bIsmOsYMY7Pqfm/5rteT5GA==", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.4.1.tgz", + "integrity": "sha512-Lo7lSIcpswa2Kv4HEeUcGYqaasMUQNpjTXpV0N8G6jXgZaQurqp7E8NGYeGbDXnb48czmHWbzDL4S3+BbK0VzA==", "dependencies": { + "@docusaurus/core": "2.4.1", "@docusaurus/logger": "2.4.1", - "@svgr/webpack": "^6.2.1", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/module-type-aliases": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", + "@types/react-router-config": "^5.0.6", + "combine-promises": "^1.1.0", "fs-extra": "^10.1.0", - "github-slugger": "^1.4.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", + "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", "tslib": "^2.4.0", - "url-loader": "^4.1.1", + "utility-types": "^3.10.0", "webpack": "^5.73.0" }, "engines": { "node": ">=16.14" }, "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } + "react": "^16.8.4 || ^17.0.0", + "react-dom": "^16.8.4 || ^17.0.0" } }, - "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/utils-common": { + "node_modules/@docusaurus/plugin-content-pages": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.1.tgz", - "integrity": "sha512-bCVGdZU+z/qVcIiEQdyx0K13OC5mYwxhSuDUR95oFbKVuXYRrTVrwZIqQljuo1fyJvFTKHiL9L9skQOPokuFNQ==", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.4.1.tgz", + "integrity": "sha512-/UjuH/76KLaUlL+o1OvyORynv6FURzjurSjvn2lbWTFc4tpYY2qLYTlKpTCBVPhlLUQsfyFnshEJDLmPneq2oA==", "dependencies": { - "tslib": "^2.4.0" + "@docusaurus/core": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", + "fs-extra": "^10.1.0", + "tslib": "^2.4.0", + "webpack": "^5.73.0" }, "engines": { "node": ">=16.14" }, "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } + "react": "^16.8.4 || ^17.0.0", + "react-dom": "^16.8.4 || ^17.0.0" } }, - "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/utils-validation": { + "node_modules/@docusaurus/plugin-google-analytics": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.1.tgz", - "integrity": "sha512-unII3hlJlDwZ3w8U+pMO3Lx3RhI4YEbY3YNsQj4yzrkZzlpqZOLuAiZK2JyULnD+TKbceKU0WyWkQXtYbLNDFA==", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.4.1.tgz", + "integrity": "sha512-dyZJdJiCoL+rcfnm0RPkLt/o732HvLiEwmtoNzOoz9MSZz117UH2J6U2vUDtzUzwtFLIf32KkeyzisbwUCgcaQ==", "dependencies": { - "@docusaurus/logger": "2.4.1", - "@docusaurus/utils": "2.4.1", - "joi": "^17.6.0", - "js-yaml": "^4.1.0", + "@docusaurus/core": "2.4.1", + "@docusaurus/types": "2.4.1", + "@docusaurus/utils-validation": "2.4.1", "tslib": "^2.4.0" }, "engines": { "node": ">=16.14" + }, + "peerDependencies": { + "react": "^16.8.4 || ^17.0.0", + "react-dom": "^16.8.4 || ^17.0.0" } }, - "node_modules/@docusaurus/theme-common": { + "node_modules/@docusaurus/react-loadable": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", + "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", + "dependencies": { + "@types/react": "*", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/@docusaurus/theme-classic": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-2.4.1.tgz", - "integrity": "sha512-G7Zau1W5rQTaFFB3x3soQoZpkgMbl/SYNG8PfMFIjKa3M3q8n0m/GRf5/H/e5BqOvt8c+ZWIXGCiz+kUCSHovA==", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-2.4.1.tgz", + "integrity": "sha512-Rz0wKUa+LTW1PLXmwnf8mn85EBzaGSt6qamqtmnh9Hflkc+EqiYMhtUJeLdV+wsgYq4aG0ANc+bpUDpsUhdnwg==", "dependencies": { + "@docusaurus/core": "2.4.1", "@docusaurus/mdx-loader": "2.4.1", "@docusaurus/module-type-aliases": "2.4.1", "@docusaurus/plugin-content-blog": "2.4.1", "@docusaurus/plugin-content-docs": "2.4.1", "@docusaurus/plugin-content-pages": "2.4.1", + "@docusaurus/theme-common": "2.4.1", + "@docusaurus/theme-translations": "2.4.1", + "@docusaurus/types": "2.4.1", "@docusaurus/utils": "2.4.1", "@docusaurus/utils-common": "2.4.1", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", + "@docusaurus/utils-validation": "2.4.1", + "@mdx-js/react": "^1.6.22", "clsx": "^1.2.1", - "parse-numeric-range": "^1.3.0", + "copy-text-to-clipboard": "^3.0.1", + "infima": "0.2.0-alpha.43", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.4.14", "prism-react-renderer": "^1.3.5", + "prismjs": "^1.28.0", + "react-router-dom": "^5.3.3", + "rtlcss": "^3.5.0", "tslib": "^2.4.0", - "use-sync-external-store": "^1.2.0", "utility-types": "^3.10.0" }, "engines": { @@ -3739,40 +2416,27 @@ "react-dom": "^16.8.4 || ^17.0.0" } }, - "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/logger": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.1.tgz", - "integrity": "sha512-5h5ysIIWYIDHyTVd8BjheZmQZmEgWDR54aQ1BX9pjFfpyzFo5puKXKYrYJXbjEHGyVhEzmB9UXwbxGfaZhOjcg==", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - } - }, - "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/mdx-loader": { + "node_modules/@docusaurus/theme-common": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.1.tgz", - "integrity": "sha512-4KhUhEavteIAmbBj7LVFnrVYDiU51H5YWW1zY6SmBSte/YLhDutztLTBE0PQl1Grux1jzUJeaSvAzHpTn6JJDQ==", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-2.4.1.tgz", + "integrity": "sha512-G7Zau1W5rQTaFFB3x3soQoZpkgMbl/SYNG8PfMFIjKa3M3q8n0m/GRf5/H/e5BqOvt8c+ZWIXGCiz+kUCSHovA==", "dependencies": { - "@babel/parser": "^7.18.8", - "@babel/traverse": "^7.18.8", - "@docusaurus/logger": "2.4.1", + "@docusaurus/mdx-loader": "2.4.1", + "@docusaurus/module-type-aliases": "2.4.1", + "@docusaurus/plugin-content-blog": "2.4.1", + "@docusaurus/plugin-content-docs": "2.4.1", + "@docusaurus/plugin-content-pages": "2.4.1", "@docusaurus/utils": "2.4.1", - "@mdx-js/mdx": "^1.6.22", - "escape-html": "^1.0.3", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "image-size": "^1.0.1", - "mdast-util-to-string": "^2.0.0", - "remark-emoji": "^2.2.0", - "stringify-object": "^3.3.0", + "@docusaurus/utils-common": "2.4.1", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^1.2.1", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^1.3.5", "tslib": "^2.4.0", - "unified": "^9.2.2", - "unist-util-visit": "^2.0.3", - "url-loader": "^4.1.1", - "webpack": "^5.73.0" + "use-sync-external-store": "^1.2.0", + "utility-types": "^3.10.0" }, "engines": { "node": ">=16.14" @@ -3782,59 +2446,6 @@ "react-dom": "^16.8.4 || ^17.0.0" } }, - "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.1.tgz", - "integrity": "sha512-1lvEZdAQhKNht9aPXPoh69eeKnV0/62ROhQeFKKxmzd0zkcuE/Oc5Gpnt00y/f5bIsmOsYMY7Pqfm/5rteT5GA==", - "dependencies": { - "@docusaurus/logger": "2.4.1", - "@svgr/webpack": "^6.2.1", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "github-slugger": "^1.4.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.4.0", - "url-loader": "^4.1.1", - "webpack": "^5.73.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/utils-common": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.1.tgz", - "integrity": "sha512-bCVGdZU+z/qVcIiEQdyx0K13OC5mYwxhSuDUR95oFbKVuXYRrTVrwZIqQljuo1fyJvFTKHiL9L9skQOPokuFNQ==", - "dependencies": { - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, "node_modules/@docusaurus/theme-translations": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-2.4.1.tgz", @@ -3867,11 +2478,11 @@ } }, "node_modules/@docusaurus/utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.0.tgz", - "integrity": "sha512-89hLYkvtRX92j+C+ERYTuSUK6nF9bGM32QThcHPg2EDDHVw6FzYQXmX6/p+pU5SDyyx5nBlE4qXR92RxCAOqfg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.1.tgz", + "integrity": "sha512-1lvEZdAQhKNht9aPXPoh69eeKnV0/62ROhQeFKKxmzd0zkcuE/Oc5Gpnt00y/f5bIsmOsYMY7Pqfm/5rteT5GA==", "dependencies": { - "@docusaurus/logger": "2.4.0", + "@docusaurus/logger": "2.4.1", "@svgr/webpack": "^6.2.1", "escape-string-regexp": "^4.0.0", "file-loader": "^6.2.0", @@ -3901,9 +2512,9 @@ } }, "node_modules/@docusaurus/utils-common": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.0.tgz", - "integrity": "sha512-zIMf10xuKxddYfLg5cS19x44zud/E9I7lj3+0bv8UIs0aahpErfNrGhijEfJpAfikhQ8tL3m35nH3hJ3sOG82A==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.1.tgz", + "integrity": "sha512-bCVGdZU+z/qVcIiEQdyx0K13OC5mYwxhSuDUR95oFbKVuXYRrTVrwZIqQljuo1fyJvFTKHiL9L9skQOPokuFNQ==", "dependencies": { "tslib": "^2.4.0" }, @@ -3920,12 +2531,12 @@ } }, "node_modules/@docusaurus/utils-validation": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.0.tgz", - "integrity": "sha512-IrBsBbbAp6y7mZdJx4S4pIA7dUyWSA0GNosPk6ZJ0fX3uYIEQgcQSGIgTeSC+8xPEx3c16o03en1jSDpgQgz/w==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.1.tgz", + "integrity": "sha512-unII3hlJlDwZ3w8U+pMO3Lx3RhI4YEbY3YNsQj4yzrkZzlpqZOLuAiZK2JyULnD+TKbceKU0WyWkQXtYbLNDFA==", "dependencies": { - "@docusaurus/logger": "2.4.0", - "@docusaurus/utils": "2.4.0", + "@docusaurus/logger": "2.4.1", + "@docusaurus/utils": "2.4.1", "joi": "^17.6.0", "js-yaml": "^4.1.0", "tslib": "^2.4.0" @@ -7654,14 +6265,14 @@ } }, "node_modules/docusaurus-plugin-sass": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/docusaurus-plugin-sass/-/docusaurus-plugin-sass-0.2.3.tgz", - "integrity": "sha512-FbaE06K8NF8SPUYTwiG+83/jkXrwHJ/Afjqz3SUIGon6QvFwSSoKOcoxGQmUBnjTOk+deUONDx8jNWsegFJcBQ==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/docusaurus-plugin-sass/-/docusaurus-plugin-sass-0.2.5.tgz", + "integrity": "sha512-Z+D0fLFUKcFpM+bqSUmqKIU+vO+YF1xoEQh5hoFreg2eMf722+siwXDD+sqtwU8E4MvVpuvsQfaHwODNlxJAEg==", "dependencies": { "sass-loader": "^10.1.1" }, "peerDependencies": { - "@docusaurus/core": "^2.0.0-beta", + "@docusaurus/core": "^2.0.0-beta || ^3.0.0-alpha", "sass": "^1.30.0" } }, @@ -11615,9 +10226,9 @@ } }, "node_modules/postcss-sort-media-queries": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.3.0.tgz", - "integrity": "sha512-jAl8gJM2DvuIJiI9sL1CuiHtKM4s5aEIomkU8G3LFvbP+p8i7Sz8VV63uieTgoewGqKbi+hxBTiOKJlB35upCg==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.4.1.tgz", + "integrity": "sha512-QDESFzDDGKgpiIh4GYXsSy6sek2yAwQx1JASl5AxBtU1Lq2JfKBljIPNdil989NcSKRQX1ToiaKphImtBuhXWw==", "dependencies": { "sort-css-media-queries": "2.1.0" }, diff --git a/website/package.json b/website/package.json index 4aeba248300..d5dbb792c5f 100644 --- a/website/package.json +++ b/website/package.json @@ -55,7 +55,7 @@ "@typescript-eslint/eslint-plugin": "^5.57.0", "@typescript-eslint/parser": "^5.54.0", "dir-compare": "^4.0.0", - "prettier": "2.8.8", + "prettier": "^2.8.8", "typescript": "^4.8.3" } } diff --git a/website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx b/website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx index b2ff96337a5..da088ee1748 100644 --- a/website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx +++ b/website/versioned_docs/version-0.20/getting-started/build-a-sample-app.mdx @@ -52,7 +52,7 @@ To convert this simple command line application to a basic Yew web application, #### Update Cargo.toml -Add `yew` to the list of dependencies. +Add `yew` to the list of dependencies editing file: ```toml title=Cargo.toml [package] @@ -64,6 +64,8 @@ edition = "2021" yew = { version = "0.20.0", features = ["csr"] } ``` +or using `cargo add yew -F csr`. + :::info You only need feature `csr` if you are building an application. @@ -137,7 +139,24 @@ Run the following command to build and serve the application locally. trunk serve ``` +:::info +Add option '--open' to open your default browser `trunk serve --open`. +::: + Trunk will rebuild your application if you modify any of its source code files. +This will fail if the socket is being used by another application. +By default server will listening at address '127.0.0.1' and port '8080' => [http://localhost:8080](http://127.0.0.1:8080). +To change it, create the following file and edit as needed: + +```toml title="Trunk.toml" +[serve] +# The address to serve on LAN. +address = "127.0.0.1" +# The address to serve on WAN. +# address = "0.0.0.0" +# The port to serve on. +port = 8000 +``` ## Congratulations diff --git a/website/versioned_docs/version-0.20/tutorial/index.mdx b/website/versioned_docs/version-0.20/tutorial/index.mdx index 83e70685449..573b61d49ef 100644 --- a/website/versioned_docs/version-0.20/tutorial/index.mdx +++ b/website/versioned_docs/version-0.20/tutorial/index.mdx @@ -121,8 +121,22 @@ trunk serve --open ``` Trunk will open your application in your default browser, watch the project directory and helpfully rebuild your -application if you modify any source files. If you are curious, you can run `trunk help` and `trunk help ` -for more details on what's happening. +application if you modify any source files. Remove option '--open' to not open your default browser. +This will fail if the socket is being used by another application. +By default server will listening at address '127.0.0.1' and port '8080' [http://localhost:8080](http://127.0.0.1:8080). +To change it, create the following file and edit as needed: + +```toml title="Trunk.toml" +[serve] +# The address to serve on LAN. +address = "127.0.0.1" +# The address to serve on WAN. +# address = "0.0.0.0" +# The port to serve on. +port = 8080 +``` + +If you are curious, you can run `trunk help` and `trunk help ` for more details on what's happening. ### Congratulations From a2786b1e1424cbe9ab72c258b0afb35e5ba25cf4 Mon Sep 17 00:00:00 2001 From: Tim Kurdov Date: Sat, 23 Sep 2023 13:56:06 +0100 Subject: [PATCH 08/14] Improve Context API docs (#3409) * improved context API docs, added example of struct component context producer * forgot to commit that oops --- Cargo.lock | 1 - examples/contexts/Cargo.toml | 1 - examples/contexts/src/main.rs | 3 ++ examples/contexts/src/producer.rs | 4 +- .../contexts/src/struct_component_producer.rs | 27 +++++++++++ .../yew/src/functional/hooks/use_context.rs | 2 +- website/docs/concepts/contexts.mdx | 46 ++++++++++++++----- 7 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 examples/contexts/src/struct_component_producer.rs diff --git a/Cargo.lock b/Cargo.lock index 3cfae99c917..f22270ec263 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -493,7 +493,6 @@ dependencies = [ name = "contexts" version = "0.1.0" dependencies = [ - "serde", "yew", "yew-agent", ] diff --git a/examples/contexts/Cargo.toml b/examples/contexts/Cargo.toml index 65097ec6e2a..cd63a9b1155 100644 --- a/examples/contexts/Cargo.toml +++ b/examples/contexts/Cargo.toml @@ -5,6 +5,5 @@ edition = "2021" license = "MIT OR Apache-2.0" [dependencies] -serde = { version = "1.0", features = ["derive"] } yew = { path = "../../packages/yew", features = ["csr"] } yew-agent = { path = "../../packages/yew-agent" } diff --git a/examples/contexts/src/main.rs b/examples/contexts/src/main.rs index d6531e49be1..4512ee3aa40 100644 --- a/examples/contexts/src/main.rs +++ b/examples/contexts/src/main.rs @@ -1,10 +1,12 @@ mod msg_ctx; mod producer; +mod struct_component_producer; mod struct_component_subscriber; mod subscriber; use msg_ctx::MessageProvider; use producer::Producer; +use struct_component_producer::StructComponentProducer; use struct_component_subscriber::StructComponentSubscriber; use subscriber::Subscriber; use yew::prelude::*; @@ -14,6 +16,7 @@ pub fn App() -> Html { html! { + diff --git a/examples/contexts/src/producer.rs b/examples/contexts/src/producer.rs index 9eddc57a47c..1a1aaadcaac 100644 --- a/examples/contexts/src/producer.rs +++ b/examples/contexts/src/producer.rs @@ -6,10 +6,8 @@ use super::msg_ctx::MessageContext; pub fn Producer() -> Html { let msg_ctx = use_context::().unwrap(); - let onclick = Callback::from(move |_| msg_ctx.dispatch("Message Received.".to_string())); - html! { - } diff --git a/examples/contexts/src/struct_component_producer.rs b/examples/contexts/src/struct_component_producer.rs new file mode 100644 index 00000000000..49e1f02d6c5 --- /dev/null +++ b/examples/contexts/src/struct_component_producer.rs @@ -0,0 +1,27 @@ +use yew::prelude::*; + +use super::msg_ctx::MessageContext; + +pub struct StructComponentProducer; + +impl Component for StructComponentProducer { + type Message = (); + type Properties = (); + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, ctx: &Context) -> Html { + let (msg_ctx, _) = ctx + .link() + .context::(Callback::noop()) + .expect("No Message Context Provided"); + + html! { + + } + } +} diff --git a/packages/yew/src/functional/hooks/use_context.rs b/packages/yew/src/functional/hooks/use_context.rs index c85cadfa521..9310192fbf1 100644 --- a/packages/yew/src/functional/hooks/use_context.rs +++ b/packages/yew/src/functional/hooks/use_context.rs @@ -11,7 +11,7 @@ use crate::functional::{Hook, HookContext}; /// is returned. A component which calls `use_context` will re-render when the data of the context /// changes. /// -/// More information about contexts and how to define and consume them can be found on [Yew Docs](https://yew.rs). +/// More information about contexts and how to define and consume them can be found on [Yew Docs](https://yew.rs/docs/concepts/contexts). /// /// # Example /// diff --git a/website/docs/concepts/contexts.mdx b/website/docs/concepts/contexts.mdx index 230f8daa6c4..bbe65f7f3c1 100644 --- a/website/docs/concepts/contexts.mdx +++ b/website/docs/concepts/contexts.mdx @@ -96,35 +96,57 @@ A context provider is required to consume the context. `ContextProvider`, whe The children are re-rendered when the context changes. A struct is used to define what data is to be passed. The `ContextProvider` can be used as: ```rust -use std::rc::Rc; use yew::prelude::*; + +/// App theme #[derive(Clone, Debug, PartialEq)] struct Theme { foreground: String, background: String, } +/// Main component #[function_component] -fn NavButton() -> Html { - let theme = use_context::(); +pub fn App() -> Html { + let ctx = use_state(|| Theme { + foreground: "#000000".to_owned(), + background: "#eeeeee".to_owned(), + }); html! { - // use theme + // `ctx` is type `Rc>` while we need `Theme` + // so we deref it. + // It derefs to `&Theme`, hence the clone + context={(*ctx).clone()}> + // Every child here and their children will have access to this context. + + > } } +/// The toolbar. +/// This component has access to the context #[function_component] -fn App() -> Html { - let theme = use_memo((), |_| Theme { - foreground: "yellow".to_owned(), - background: "pink".to_owned(), - }); +pub fn Toolbar() -> Html { + html! { +
+ +
+ } +} + +/// Button placed in `Toolbar`. +/// As this component is a child of `ThemeContextProvider` in the component tree, it also has access +/// to the context. +#[function_component] +pub fn ThemedButton() -> Html { + let theme = use_context::().expect("no ctx found"); html! { - > context={theme}> - - >> + } } ``` From ca2aa2a4a6c0aa07bb636c68c0ffe07ba65804b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 Sep 2023 14:57:06 +0200 Subject: [PATCH 09/14] Bump the cargo dependencies with 36 updates (#3408) * Bump the cargo-deps group with 36 updates Bumps the cargo-deps group with 36 updates: | Package | From | To | | --- | --- | --- | | [proc-macro2](https://github.com/dtolnay/proc-macro2) | `1.0.63` | `1.0.67` | | [quote](https://github.com/dtolnay/quote) | `1.0.29` | `1.0.33` | | [syn](https://github.com/dtolnay/syn) | `2.0.27` | `2.0.37` | | [rustversion](https://github.com/dtolnay/rustversion) | `1.0.12` | `1.0.14` | | [trybuild](https://github.com/dtolnay/trybuild) | `1.0.80` | `1.0.85` | | [gloo-worker](https://github.com/rustwasm/gloo) | `0.3.0` | `0.4.0` | | [serde](https://github.com/serde-rs/serde) | `1.0.168` | `1.0.188` | | [prettyplease](https://github.com/dtolnay/prettyplease) | `0.2.12` | `0.2.15` | | [gloo](https://github.com/rustwasm/gloo) | `0.8.1` | `0.10.0` | | [urlencoding](https://github.com/kornelski/rust_urlencoding) | `2.1.2` | `2.1.3` | | [slab](https://github.com/tokio-rs/slab) | `0.4.8` | `0.4.9` | | [thiserror](https://github.com/dtolnay/thiserror) | `1.0.44` | `1.0.48` | | [implicit-clone](https://github.com/yewstack/implicit-clone) | `0.4.0` | `0.4.1` | | [tokio](https://github.com/tokio-rs/tokio) | `1.29.0` | `1.32.0` | | [jemallocator](https://github.com/tikv/jemallocator) | `0.5.0` | `0.5.4` | | [average](https://github.com/vks/average) | `0.13.1` | `0.14.1` | | [tabled](https://github.com/zhiburt/tabled) | `0.12.2` | `0.14.0` | | [indicatif](https://github.com/console-rs/indicatif) | `0.17.5` | `0.17.6` | | [serde_json](https://github.com/serde-rs/json) | `1.0.104` | `1.0.107` | | [clap](https://github.com/clap-rs/clap) | `4.3.9` | `4.4.4` | | [anyhow](https://github.com/dtolnay/anyhow) | `1.0.71` | `1.0.75` | | [chrono](https://github.com/chronotope/chrono) | `0.4.26` | `0.4.31` | | [git2](https://github.com/rust-lang/git2-rs) | `0.17.2` | `0.18.1` | | [regex](https://github.com/rust-lang/regex) | `1.8.4` | `1.9.4` | | [reqwest](https://github.com/seanmonstar/reqwest) | `0.11.18` | `0.11.20` | | [semver](https://github.com/dtolnay/semver) | `1.0.17` | `1.0.18` | | [gloo-net](https://github.com/rustwasm/gloo) | `0.3.0` | `0.4.0` | | [base64](https://github.com/marshallpierce/rust-base64) | `0.21.2` | `0.21.4` | | [strum_macros](https://github.com/Peternator7/strum) | `0.25.0` | `0.25.2` | | [log](https://github.com/rust-lang/log) | `0.4.19` | `0.4.20` | | [fake](https://github.com/cksac/fake-rs) | `2.6.1` | `2.8.0` | | [time](https://github.com/time-rs/time) | `0.3.22` | `0.3.28` | | [uuid](https://github.com/uuid-rs/uuid) | `1.4.0` | `1.4.1` | | [bytes](https://github.com/tokio-rs/bytes) | `1.4.0` | `1.5.0` | | [axum](https://github.com/tokio-rs/axum) | `0.6.18` | `0.6.20` | | [postcard](https://github.com/jamesmunns/postcard) | `1.0.6` | `1.0.7` | Updates `proc-macro2` from 1.0.63 to 1.0.67 - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.63...1.0.67) Updates `quote` from 1.0.29 to 1.0.33 - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.29...1.0.33) Updates `syn` from 2.0.27 to 2.0.37 - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/2.0.27...2.0.37) Updates `rustversion` from 1.0.12 to 1.0.14 - [Release notes](https://github.com/dtolnay/rustversion/releases) - [Commits](https://github.com/dtolnay/rustversion/compare/1.0.12...1.0.14) Updates `trybuild` from 1.0.80 to 1.0.85 - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.80...1.0.85) Updates `gloo-worker` from 0.3.0 to 0.4.0 - [Release notes](https://github.com/rustwasm/gloo/releases) - [Changelog](https://github.com/rustwasm/gloo/blob/master/CHANGELOG.md) - [Commits](https://github.com/rustwasm/gloo/compare/0.3.0...0.4.0) Updates `serde` from 1.0.168 to 1.0.188 - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.168...v1.0.188) Updates `prettyplease` from 0.2.12 to 0.2.15 - [Release notes](https://github.com/dtolnay/prettyplease/releases) - [Commits](https://github.com/dtolnay/prettyplease/compare/0.2.12...0.2.15) Updates `gloo` from 0.8.1 to 0.10.0 - [Release notes](https://github.com/rustwasm/gloo/releases) - [Changelog](https://github.com/rustwasm/gloo/blob/master/CHANGELOG.md) - [Commits](https://github.com/rustwasm/gloo/commits) Updates `urlencoding` from 2.1.2 to 2.1.3 - [Commits](https://github.com/kornelski/rust_urlencoding/commits) Updates `slab` from 0.4.8 to 0.4.9 - [Release notes](https://github.com/tokio-rs/slab/releases) - [Changelog](https://github.com/tokio-rs/slab/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/slab/compare/v0.4.8...v0.4.9) Updates `thiserror` from 1.0.44 to 1.0.48 - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.44...1.0.48) Updates `implicit-clone` from 0.4.0 to 0.4.1 - [Commits](https://github.com/yewstack/implicit-clone/compare/v0.4.0...v0.4.1) Updates `tokio` from 1.29.0 to 1.32.0 - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.29.0...tokio-1.32.0) Updates `jemallocator` from 0.5.0 to 0.5.4 - [Release notes](https://github.com/tikv/jemallocator/releases) - [Changelog](https://github.com/tikv/jemallocator/blob/main/CHANGELOG.md) - [Commits](https://github.com/tikv/jemallocator/compare/0.5.0...0.5.4) Updates `average` from 0.13.1 to 0.14.1 - [Commits](https://github.com/vks/average/commits) Updates `tabled` from 0.12.2 to 0.14.0 - [Changelog](https://github.com/zhiburt/tabled/blob/master/CHANGELOG.md) - [Commits](https://github.com/zhiburt/tabled/commits/v0.14.0) Updates `indicatif` from 0.17.5 to 0.17.6 - [Release notes](https://github.com/console-rs/indicatif/releases) - [Commits](https://github.com/console-rs/indicatif/compare/0.17.5...0.17.6) Updates `serde_json` from 1.0.104 to 1.0.107 - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.104...v1.0.107) Updates `clap` from 4.3.9 to 4.4.4 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.3.9...v4.4.4) Updates `anyhow` from 1.0.71 to 1.0.75 - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.71...1.0.75) Updates `chrono` from 0.4.26 to 0.4.31 - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.26...v0.4.31) Updates `git2` from 0.17.2 to 0.18.1 - [Changelog](https://github.com/rust-lang/git2-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/git2-rs/compare/0.17.2...git2-0.18.1) Updates `regex` from 1.8.4 to 1.9.4 - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.8.4...1.9.4) Updates `reqwest` from 0.11.18 to 0.11.20 - [Release notes](https://github.com/seanmonstar/reqwest/releases) - [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md) - [Commits](https://github.com/seanmonstar/reqwest/compare/v0.11.18...v0.11.20) Updates `semver` from 1.0.17 to 1.0.18 - [Release notes](https://github.com/dtolnay/semver/releases) - [Commits](https://github.com/dtolnay/semver/compare/1.0.17...1.0.18) Updates `gloo-net` from 0.3.0 to 0.4.0 - [Release notes](https://github.com/rustwasm/gloo/releases) - [Changelog](https://github.com/rustwasm/gloo/blob/master/CHANGELOG.md) - [Commits](https://github.com/rustwasm/gloo/compare/0.3.0...0.4.0) Updates `base64` from 0.21.2 to 0.21.4 - [Changelog](https://github.com/marshallpierce/rust-base64/blob/master/RELEASE-NOTES.md) - [Commits](https://github.com/marshallpierce/rust-base64/compare/v0.21.2...v0.21.4) Updates `strum_macros` from 0.25.0 to 0.25.2 - [Changelog](https://github.com/Peternator7/strum/blob/master/CHANGELOG.md) - [Commits](https://github.com/Peternator7/strum/commits) Updates `log` from 0.4.19 to 0.4.20 - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.19...0.4.20) Updates `fake` from 2.6.1 to 2.8.0 - [Commits](https://github.com/cksac/fake-rs/commits) Updates `time` from 0.3.22 to 0.3.28 - [Release notes](https://github.com/time-rs/time/releases) - [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md) - [Commits](https://github.com/time-rs/time/compare/v0.3.22...v0.3.28) Updates `uuid` from 1.4.0 to 1.4.1 - [Release notes](https://github.com/uuid-rs/uuid/releases) - [Commits](https://github.com/uuid-rs/uuid/compare/1.4.0...1.4.1) Updates `bytes` from 1.4.0 to 1.5.0 - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.4.0...v1.5.0) Updates `axum` from 0.6.18 to 0.6.20 - [Release notes](https://github.com/tokio-rs/axum/releases) - [Changelog](https://github.com/tokio-rs/axum/blob/main/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/axum/compare/axum-v0.6.18...axum-v0.6.20) Updates `postcard` from 1.0.6 to 1.0.7 - [Release notes](https://github.com/jamesmunns/postcard/releases) - [Changelog](https://github.com/jamesmunns/postcard/blob/main/CHANGELOG.md) - [Commits](https://github.com/jamesmunns/postcard/compare/v1.0.6...v1.0.7) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: rustversion dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: gloo-worker dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-deps - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: prettyplease dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: gloo dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-deps - dependency-name: urlencoding dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: slab dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: implicit-clone dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: tokio dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-deps - dependency-name: jemallocator dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: average dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-deps - dependency-name: tabled dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-deps - dependency-name: indicatif dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-deps - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: git2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-deps - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-deps - dependency-name: reqwest dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: semver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: gloo-net dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-deps - dependency-name: base64 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: strum_macros dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: log dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: fake dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-deps - dependency-name: time dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: uuid dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-deps - dependency-name: axum dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps - dependency-name: postcard dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-deps ... Signed-off-by: dependabot[bot] * bless stderr files after syn update --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Muhammad Hamza --- Cargo.lock | 559 +++++++++++------- examples/async_clock/Cargo.toml | 2 +- examples/boids/Cargo.toml | 2 +- examples/counter/Cargo.toml | 2 +- examples/dyn_create_destroy_apps/Cargo.toml | 4 +- examples/file_upload/Cargo.toml | 4 +- examples/function_memory_game/Cargo.toml | 2 +- examples/function_router/Cargo.toml | 2 +- examples/function_todomvc/Cargo.toml | 2 +- examples/futures/Cargo.toml | 2 +- examples/game_of_life/Cargo.toml | 2 +- examples/inner_html/Cargo.toml | 2 +- examples/keyed_list/Cargo.toml | 2 +- examples/mount_point/Cargo.toml | 2 +- examples/password_strength/Cargo.toml | 2 +- examples/portals/Cargo.toml | 2 +- examples/router/Cargo.toml | 2 +- examples/simple_ssr/Cargo.toml | 10 +- examples/ssr_router/Cargo.toml | 2 +- examples/suspense/Cargo.toml | 2 +- examples/timer/Cargo.toml | 2 +- examples/timer_functional/Cargo.toml | 2 +- examples/todomvc/Cargo.toml | 2 +- examples/two_apps/Cargo.toml | 2 +- examples/web_worker_fib/Cargo.toml | 2 +- examples/web_worker_prime/Cargo.toml | 2 +- packages/yew-agent/Cargo.toml | 4 +- .../yew-macro/tests/derive_props/fail.stderr | 2 +- .../tests/html_macro/component-fail.stderr | 4 +- packages/yew-router/Cargo.toml | 4 +- packages/yew/Cargo.toml | 10 +- tools/benchmark-ssr/Cargo.toml | 14 +- tools/changelog/Cargo.toml | 2 +- tools/website-test/Cargo.toml | 4 +- 34 files changed, 414 insertions(+), 251 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f22270ec263..278d5629c0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,16 +43,15 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] @@ -82,9 +81,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -92,9 +91,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "anymap2" @@ -110,7 +109,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.37", ] [[package]] @@ -119,7 +118,7 @@ version = "0.0.1" dependencies = [ "chrono", "futures 0.3.28", - "gloo-net", + "gloo-net 0.4.0", "yew", ] @@ -140,9 +139,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "average" -version = "0.13.1" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843ec791d3f24503bbf72bbd5e49a3ab4dbb4bcd0a8ef6b0c908efa73caa27b1" +checksum = "6d804c74bb2d66e9b7047658d21af0f1c937d7d2466410cbf1aed3b0c04048d4" dependencies = [ "easy-cast", "float-ord", @@ -151,13 +150,13 @@ dependencies = [ [[package]] name = "axum" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", - "bitflags", + "bitflags 1.3.2", "bytes", "futures-util", "http", @@ -221,9 +220,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64ct" @@ -286,6 +285,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + [[package]] name = "block-buffer" version = "0.10.4" @@ -301,7 +306,7 @@ version = "0.1.0" dependencies = [ "anyhow", "getrandom", - "gloo", + "gloo 0.10.0", "rand", "serde", "web-sys", @@ -334,9 +339,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" @@ -371,53 +376,50 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", - "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets 0.48.1", ] [[package]] name = "clap" -version = "4.3.9" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bba77a07e4489fb41bd90e8d4201c3eb246b3c2c9ea2ba0bddd6c1d1df87db7d" +checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.3.9" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9b4a88bb4bc35d3d6f65a21b0f0bafe9c894fa00978de242c555ec28bea1c0" +checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" dependencies = [ "anstream", "anstyle", - "bitflags", "clap_lex", "strsim", ] [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.37", ] [[package]] @@ -523,7 +525,7 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" name = "counter" version = "0.1.1" dependencies = [ - "gloo", + "gloo 0.10.0", "js-sys", "wasm-bindgen", "yew", @@ -596,6 +598,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" + [[package]] name = "derive_builder" version = "0.12.0" @@ -654,7 +662,7 @@ dependencies = [ name = "dyn_create_destroy_apps" version = "0.1.0" dependencies = [ - "gloo", + "gloo 0.10.0", "js-sys", "slab", "wasm-bindgen", @@ -664,9 +672,9 @@ dependencies = [ [[package]] name = "easy-cast" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd102ee8c418348759919b83b81cdbdc933ffe29740b903df448b4bafaa348e" +checksum = "10936778145f3bea71fd9bf61332cce28c28e96a380714f7ab34838b80733fd6" dependencies = [ "libm", ] @@ -734,9 +742,9 @@ dependencies = [ [[package]] name = "fake" -version = "2.6.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a44c765350db469b774425ff1c833890b16ceb9612fb5d7c4bbdf4a1b55f876" +checksum = "9af7b0c58ac9d03169e27f080616ce9f64004edca3d2ef4147a811c21b23b319" dependencies = [ "rand", "unidecode", @@ -765,8 +773,8 @@ dependencies = [ name = "file_upload" version = "0.1.0" dependencies = [ - "base64 0.21.2", - "gloo", + "base64 0.21.4", + "gloo 0.10.0", "js-sys", "web-sys", "yew", @@ -813,7 +821,7 @@ name = "function_memory_game" version = "0.1.0" dependencies = [ "getrandom", - "gloo", + "gloo 0.10.0", "nanoid", "rand", "serde", @@ -828,7 +836,7 @@ name = "function_router" version = "0.1.0" dependencies = [ "getrandom", - "gloo", + "gloo 0.10.0", "instant", "lipsum", "log", @@ -844,7 +852,7 @@ dependencies = [ name = "function_todomvc" version = "0.1.0" dependencies = [ - "gloo", + "gloo 0.10.0", "serde", "strum", "strum_macros", @@ -856,7 +864,7 @@ dependencies = [ name = "futures" version = "0.1.0" dependencies = [ - "gloo", + "gloo 0.10.0", "pulldown-cmark", "wasm-bindgen", "wasm-bindgen-futures", @@ -920,7 +928,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.37", ] [[package]] @@ -958,7 +966,7 @@ name = "game_of_life" version = "0.1.4" dependencies = [ "getrandom", - "gloo", + "gloo 0.10.0", "log", "rand", "wasm-logger", @@ -984,7 +992,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -996,11 +1004,11 @@ checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "git2" -version = "0.17.2" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b989d6a7ca95a362cf2cfc5ad688b3a467be1f87e480b8dad07fee8c79b0044" +checksum = "fbf97ba92db08df386e10c8ede66a2a0369bd277090afd8710e19e38de9ec0cd" dependencies = [ - "bitflags", + "bitflags 2.4.0", "libc", "libgit2-sys", "log", @@ -1021,26 +1029,58 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28999cda5ef6916ffd33fb4a7b87e1de633c47c0dc6d97905fee1cdaa142b94d" dependencies = [ - "gloo-console", - "gloo-dialogs", - "gloo-events", - "gloo-file", - "gloo-history", - "gloo-net", - "gloo-render", - "gloo-storage", - "gloo-timers", - "gloo-utils", + "gloo-console 0.2.3", + "gloo-dialogs 0.1.1", + "gloo-events 0.1.2", + "gloo-file 0.2.3", + "gloo-history 0.1.4", + "gloo-net 0.3.1", + "gloo-render 0.1.1", + "gloo-storage 0.2.2", + "gloo-timers 0.2.6", + "gloo-utils 0.1.7", "gloo-worker 0.2.1", ] +[[package]] +name = "gloo" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd35526c28cc55c1db77aed6296de58677dbab863b118483a27845631d870249" +dependencies = [ + "gloo-console 0.3.0", + "gloo-dialogs 0.2.0", + "gloo-events 0.2.0", + "gloo-file 0.3.0", + "gloo-history 0.2.0", + "gloo-net 0.4.0", + "gloo-render 0.2.0", + "gloo-storage 0.3.0", + "gloo-timers 0.3.0", + "gloo-utils 0.2.0", + "gloo-worker 0.4.0", +] + [[package]] name = "gloo-console" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82b7ce3c05debe147233596904981848862b068862e9ec3e34be446077190d3f" dependencies = [ - "gloo-utils", + "gloo-utils 0.1.7", + "js-sys", + "serde", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-console" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a17868f56b4a24f677b17c8cb69958385102fa879418052d60b50bc1727e261" +dependencies = [ + "gloo-utils 0.2.0", "js-sys", "serde", "wasm-bindgen", @@ -1057,6 +1097,16 @@ dependencies = [ "web-sys", ] +[[package]] +name = "gloo-dialogs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4748e10122b01435750ff530095b1217cf6546173459448b83913ebe7815df" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gloo-events" version = "0.1.2" @@ -1067,14 +1117,36 @@ dependencies = [ "web-sys", ] +[[package]] +name = "gloo-events" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c26fb45f7c385ba980f5fa87ac677e363949e065a083722697ef1b2cc91e41" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gloo-file" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8d5564e570a38b43d78bdc063374a0c3098c4f0d64005b12f9bbe87e869b6d7" +dependencies = [ + "gloo-events 0.1.2", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-file" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97563d71863fb2824b2e974e754a81d19c4a7ec47b09ced8a0e6656b6d54bd1f" dependencies = [ "futures-channel", - "gloo-events", + "gloo-events 0.2.0", "js-sys", "wasm-bindgen", "web-sys", @@ -1086,8 +1158,24 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfd137a4b629e72b8c949ec56c71ea9bd5491cc66358a0a7787e94875feec71" dependencies = [ - "gloo-events", - "gloo-utils", + "gloo-events 0.1.2", + "gloo-utils 0.1.7", + "serde", + "serde-wasm-bindgen", + "serde_urlencoded", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-history" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91be9f3dd048f35a59c8de3d716ef6d568360078c73ed35a7700776ed53153c8" +dependencies = [ + "gloo-events 0.2.0", + "gloo-utils 0.2.0", "serde", "serde-wasm-bindgen", "serde_urlencoded", @@ -1098,14 +1186,35 @@ dependencies = [ [[package]] name = "gloo-net" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3000ef231a67d5bfee6b35f2c0f6f5c8d45b3381ef5bbbea603690ec4e539762" +checksum = "a66b4e3c7d9ed8d315fd6b97c8b1f74a7c6ecbbc2320e65ae7ed38b7068cc620" dependencies = [ "futures-channel", "futures-core", "futures-sink", - "gloo-utils", + "gloo-utils 0.1.7", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-net" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ac9e8288ae2c632fa9f8657ac70bfe38a1530f345282d7ba66a1f70b72b7dc4" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils 0.2.0", "http", "js-sys", "pin-project", @@ -1127,13 +1236,38 @@ dependencies = [ "web-sys", ] +[[package]] +name = "gloo-render" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56008b6744713a8e8d98ac3dcb7d06543d5662358c9c805b4ce2167ad4649833" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gloo-storage" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d6ab60bf5dbfd6f0ed1f7843da31b41010515c745735c970e821945ca91e480" dependencies = [ - "gloo-utils", + "gloo-utils 0.1.7", + "js-sys", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-storage" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc8031e8c92758af912f9bc08fbbadd3c6f3cfcbf6b64cdf3d6a81f0139277a" +dependencies = [ + "gloo-utils 0.2.0", "js-sys", "serde", "serde_json", @@ -1147,6 +1281,16 @@ name = "gloo-timers" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" dependencies = [ "futures-channel", "futures-core", @@ -1167,6 +1311,19 @@ dependencies = [ "web-sys", ] +[[package]] +name = "gloo-utils" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gloo-worker" version = "0.2.1" @@ -1175,8 +1332,8 @@ checksum = "13471584da78061a28306d1359dd0178d8d6fc1c7c80e5e35d27260346e0516a" dependencies = [ "anymap2", "bincode", - "gloo-console", - "gloo-utils", + "gloo-console 0.2.3", + "gloo-utils 0.1.7", "js-sys", "serde", "wasm-bindgen", @@ -1186,13 +1343,13 @@ dependencies = [ [[package]] name = "gloo-worker" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdec38f5350e6f71425895382d3f0e5e45ad78b69c9905f097a171b80c73112c" +checksum = "76495d3dd87de51da268fa3a593da118ab43eb7f8809e17eb38d3319b424e400" dependencies = [ "bincode", "futures 0.3.28", - "gloo-utils", + "gloo-utils 0.2.0", "gloo-worker-macros", "js-sys", "pinned", @@ -1212,7 +1369,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.37", ] [[package]] @@ -1262,7 +1419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ "base64 0.13.1", - "bitflags", + "bitflags 1.3.2", "bytes", "headers-core", "http", @@ -1387,7 +1544,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -1458,9 +1615,9 @@ dependencies = [ [[package]] name = "implicit-clone" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c84c395327945e71c6604eff15061c67849b9081318b4334b719bb2c11415f" +checksum = "af3d77000817fd9e7db159e8d52ed9b5941a2cdbfbdc8ca646e59887ae2b2dd1" dependencies = [ "indexmap 2.0.0", ] @@ -1487,9 +1644,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.5" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" +checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" dependencies = [ "console", "instant", @@ -1502,7 +1659,7 @@ dependencies = [ name = "inner_html" version = "0.1.0" dependencies = [ - "gloo", + "gloo 0.10.0", "web-sys", "yew", ] @@ -1575,9 +1732,9 @@ dependencies = [ [[package]] name = "jemallocator" -version = "0.5.0" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c2514137880c52b0b4822b563fadd38257c1f380858addb74a400889696ea6" +checksum = "a0de374a9f8e63150e6f5e8a60cc14c668226d7a347d8aee1a45766e3c4dd3bc" dependencies = [ "jemalloc-sys", "libc", @@ -1662,9 +1819,9 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libgit2-sys" -version = "0.15.2+1.6.4" +version = "0.16.1+1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a80df2e11fb4a61f4ba2ab42dbe7f74468da143f1a75c74e11dee7c813f694fa" +checksum = "f2a2bb3680b094add03bb3732ec520ece34da31a8cd2d633d1389d0f0fb60d0c" dependencies = [ "cc", "libc", @@ -1734,9 +1891,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "matchit" @@ -1746,9 +1903,9 @@ checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "mime" @@ -1782,7 +1939,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.48.0", ] @@ -1790,7 +1947,7 @@ dependencies = [ name = "mount_point" version = "0.1.0" dependencies = [ - "gloo", + "gloo 0.10.0", "wasm-bindgen", "web-sys", "yew", @@ -1905,7 +2062,7 @@ version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -1922,7 +2079,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.37", ] [[package]] @@ -1945,9 +2102,9 @@ dependencies = [ [[package]] name = "papergrid" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae7891b22598926e4398790c8fe6447930c72a67d36d983a49d6ce682ce83290" +checksum = "a2ccbe15f2b6db62f9a9871642746427e297b0ceb85f9a7f1ee5ff47d184d0c8" dependencies = [ "bytecount", "fnv", @@ -1983,7 +2140,7 @@ version = "0.1.0" dependencies = [ "chrono", "js-sys", - "time 0.3.22", + "time", "wasm-bindgen", "web-sys", "yew", @@ -2013,14 +2170,14 @@ checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.37", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -2055,7 +2212,7 @@ checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" name = "portals" version = "0.1.0" dependencies = [ - "gloo", + "gloo 0.10.0", "wasm-bindgen", "web-sys", "yew", @@ -2063,9 +2220,9 @@ dependencies = [ [[package]] name = "postcard" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9ee729232311d3cd113749948b689627618133b1c5012b77342c1950b25eaeb" +checksum = "d534c6e61df1c7166e636ca612d9820d486fe96ddad37f7abc671517b297488e" dependencies = [ "cobs", "heapless", @@ -2080,12 +2237,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.27", + "syn 2.0.37", ] [[package]] @@ -2130,9 +2287,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -2153,7 +2310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03b55e106e5791fa5a13abd13c85d6127312e8e09098059ca2bc9b03ca4cf488" dependencies = [ "futures 0.3.28", - "gloo", + "gloo 0.8.1", "num_cpus", "once_cell", "pin-project", @@ -2169,7 +2326,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" dependencies = [ - "bitflags", + "bitflags 1.3.2", "memchr", "unicase", ] @@ -2182,9 +2339,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quote" -version = "1.0.29" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -2225,14 +2382,26 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", @@ -2241,17 +2410,17 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "bytes", "encoding_rs", "futures-core", @@ -2293,7 +2462,7 @@ name = "router" version = "0.1.0" dependencies = [ "getrandom", - "gloo", + "gloo 0.10.0", "instant", "lipsum", "log", @@ -2326,7 +2495,7 @@ version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", @@ -2340,14 +2509,14 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", ] [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" @@ -2382,7 +2551,7 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -2401,15 +2570,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.168" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d614f89548720367ded108b3c843be93f3a341e22d5674ca0dd5cd57f34926af" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] @@ -2427,20 +2596,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.168" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fe589678c688e44177da4f27152ee2d190757271dc7f1d5b6b9f68d869d641" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.37", ] [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -2508,9 +2677,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -2531,6 +2700,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spin" version = "0.9.8" @@ -2583,22 +2762,22 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.0" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9f3bd7d2e45dcc5e265fbb88d6513e4747d8ef9444cf01a533119bce28a157" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" dependencies = [ "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.27", + "syn 2.0.37", ] [[package]] name = "suspense" version = "0.1.0" dependencies = [ - "gloo", + "gloo 0.10.0", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -2618,9 +2797,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.27" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -2635,9 +2814,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "tabled" -version = "0.12.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce69a5028cd9576063ec1f48edb2c75339fd835e6094ef3e05b3a079bf594a6" +checksum = "dfe9c3632da101aba5131ed63f9eed38665f8b3c68703a6bb18124835c1a5d22" dependencies = [ "papergrid", "tabled_derive", @@ -2682,41 +2861,31 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", -] - -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", + "syn 2.0.37", ] [[package]] name = "time" -version = "0.3.22" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ + "deranged", "serde", "time-core", ] @@ -2731,7 +2900,7 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" name = "timer" version = "0.1.0" dependencies = [ - "gloo", + "gloo 0.10.0", "js-sys", "wasm-bindgen", "yew", @@ -2741,7 +2910,7 @@ dependencies = [ name = "timer_functional" version = "0.1.0" dependencies = [ - "gloo", + "gloo 0.10.0", "js-sys", "yew", ] @@ -2765,7 +2934,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" name = "todomvc" version = "0.1.0" dependencies = [ - "gloo", + "gloo 0.10.0", "serde", "serde_derive", "strum", @@ -2776,11 +2945,10 @@ dependencies = [ [[package]] name = "tokio" -version = "1.29.0" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374442f06ee49c3a28a8fc9f01a2596fed7559c6b99b31279c3261778e77d84f" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ - "autocfg", "backtrace", "bytes", "libc", @@ -2789,7 +2957,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.4", "tokio-macros", "windows-sys 0.48.0", ] @@ -2802,7 +2970,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.37", ] [[package]] @@ -2891,7 +3059,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytes", "futures-core", "futures-util", @@ -2942,7 +3110,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.37", ] [[package]] @@ -2962,9 +3130,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "trybuild" -version = "1.0.80" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501dbdbb99861e4ab6b60eb6a7493956a9defb644fd034bc4a5ef27c693c8a3a" +checksum = "196a58260a906cedb9bf6d8034b6379d0c11f552416960452f267402ceeddff1" dependencies = [ "basic-toml", "glob", @@ -2998,7 +3166,7 @@ dependencies = [ name = "two_apps" version = "0.1.0" dependencies = [ - "gloo", + "gloo 0.10.0", "yew", ] @@ -3063,9 +3231,9 @@ dependencies = [ [[package]] name = "urlencoding" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "utf-8" @@ -3087,9 +3255,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "serde", ] @@ -3146,12 +3314,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3179,7 +3341,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.37", "wasm-bindgen-shared", ] @@ -3213,7 +3375,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.37", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3308,7 +3470,7 @@ dependencies = [ "boolinator", "derive_more", "glob", - "gloo", + "gloo 0.10.0", "js-sys", "tokio", "wasm-bindgen", @@ -3518,11 +3680,12 @@ dependencies = [ [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] @@ -3533,7 +3696,7 @@ dependencies = [ "bincode", "console_error_panic_hook", "futures 0.3.28", - "gloo", + "gloo 0.10.0", "html-escape", "implicit-clone", "indexmap 2.0.0", @@ -3558,7 +3721,7 @@ name = "yew-agent" version = "0.2.0" dependencies = [ "futures 0.3.28", - "gloo-worker 0.3.0", + "gloo-worker 0.4.0", "serde", "wasm-bindgen", "yew", @@ -3572,7 +3735,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.27", + "syn 2.0.37", "trybuild", "yew-agent", ] @@ -3588,7 +3751,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.27", + "syn 2.0.37", "trybuild", "yew", ] @@ -3597,7 +3760,7 @@ dependencies = [ name = "yew-router" version = "0.17.0" dependencies = [ - "gloo", + "gloo 0.10.0", "js-sys", "route-recognizer", "serde", @@ -3618,7 +3781,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.27", + "syn 2.0.37", "trybuild", "yew-router", ] @@ -3660,5 +3823,5 @@ dependencies = [ "lazy_static", "quick-error", "regex", - "time 0.3.22", + "time", ] diff --git a/examples/async_clock/Cargo.toml b/examples/async_clock/Cargo.toml index e2cd22750f3..c648b83031a 100644 --- a/examples/async_clock/Cargo.toml +++ b/examples/async_clock/Cargo.toml @@ -9,4 +9,4 @@ license = "MIT OR Apache-2.0" yew = { path = "../../packages/yew", features = ["csr"] } chrono = "0.4" futures = "0.3" -gloo-net = "0.3" +gloo-net = "0.4" diff --git a/examples/boids/Cargo.toml b/examples/boids/Cargo.toml index 7ea5a22c80d..1a3a1b8178c 100644 --- a/examples/boids/Cargo.toml +++ b/examples/boids/Cargo.toml @@ -12,7 +12,7 @@ getrandom = { version = "0.2", features = ["js"] } rand = "0.8" serde = { version = "1.0", features = ["derive"] } yew = { path = "../../packages/yew", features = ["csr"] } -gloo = "0.8" +gloo = "0.10" [dependencies.web-sys] version = "0.3" diff --git a/examples/counter/Cargo.toml b/examples/counter/Cargo.toml index 47bb8f10f92..381c2cc0d7f 100644 --- a/examples/counter/Cargo.toml +++ b/examples/counter/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" license = "MIT OR Apache-2.0" [dependencies] -gloo = "0.8" +gloo = "0.10" js-sys = "0.3" yew = { path = "../../packages/yew", features = ["csr"] } wasm-bindgen = "0.2" diff --git a/examples/dyn_create_destroy_apps/Cargo.toml b/examples/dyn_create_destroy_apps/Cargo.toml index 917024ed9de..7880e6ebe20 100644 --- a/examples/dyn_create_destroy_apps/Cargo.toml +++ b/examples/dyn_create_destroy_apps/Cargo.toml @@ -8,8 +8,8 @@ license = "MIT OR Apache-2.0" [dependencies] js-sys = "0.3" yew = { path = "../../packages/yew", features = ["csr"] } -slab = "0.4.8" -gloo = "0.8" +slab = "0.4.9" +gloo = "0.10" wasm-bindgen = "0.2" [dependencies.web-sys] diff --git a/examples/file_upload/Cargo.toml b/examples/file_upload/Cargo.toml index f4a80b553b8..20adf651a4f 100644 --- a/examples/file_upload/Cargo.toml +++ b/examples/file_upload/Cargo.toml @@ -8,8 +8,8 @@ license = "MIT OR Apache-2.0" [dependencies] js-sys = "0.3" yew = { path = "../../packages/yew", features = ["csr"] } -base64 = "0.21.2" -gloo = "0.8" +base64 = "0.21.4" +gloo = "0.10" [dependencies.web-sys] version = "0.3" diff --git a/examples/function_memory_game/Cargo.toml b/examples/function_memory_game/Cargo.toml index 95d986fdc7f..363e2e2b31c 100644 --- a/examples/function_memory_game/Cargo.toml +++ b/examples/function_memory_game/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" serde = { version = "1.0", features = ["derive"] } strum = "0.25" strum_macros = "0.25" -gloo = "0.8" +gloo = "0.10" nanoid = "0.4" rand = "0.8" getrandom = { version = "0.2", features = ["js"] } diff --git a/examples/function_router/Cargo.toml b/examples/function_router/Cargo.toml index 71ae3871c0c..4e3b73a3ca2 100644 --- a/examples/function_router/Cargo.toml +++ b/examples/function_router/Cargo.toml @@ -11,7 +11,7 @@ rand = { version = "0.8", features = ["small_rng"] } yew = { path = "../../packages/yew" } yew-router = { path = "../../packages/yew-router" } serde = { version = "1.0", features = ["derive"] } -gloo = "0.8" +gloo = "0.10" wasm-logger = "0.2" instant = { version = "0.1", features = ["wasm-bindgen"] } once_cell = "1" diff --git a/examples/function_todomvc/Cargo.toml b/examples/function_todomvc/Cargo.toml index d5304aed422..f6dcc2378e2 100644 --- a/examples/function_todomvc/Cargo.toml +++ b/examples/function_todomvc/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" serde = { version = "1.0", features = ["derive"] } strum = "0.25" strum_macros = "0.25" -gloo = "0.8" +gloo = "0.10" yew = { path = "../../packages/yew", features = ["csr"] } [dependencies.web-sys] diff --git a/examples/futures/Cargo.toml b/examples/futures/Cargo.toml index 1ce604b8508..bd0c70d5bc9 100644 --- a/examples/futures/Cargo.toml +++ b/examples/futures/Cargo.toml @@ -10,7 +10,7 @@ pulldown-cmark = { version = "0.9", default-features = false } wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" yew = { path = "../../packages/yew", features = ["csr"] } -gloo = "0.8" +gloo = "0.10" [dependencies.web-sys] version = "0.3" diff --git a/examples/game_of_life/Cargo.toml b/examples/game_of_life/Cargo.toml index 27c053aac5b..8b81d044a7d 100644 --- a/examples/game_of_life/Cargo.toml +++ b/examples/game_of_life/Cargo.toml @@ -15,4 +15,4 @@ log = "0.4" rand = "0.8" wasm-logger = "0.2" yew = { path = "../../packages/yew", features = ["csr"] } -gloo = "0.8" +gloo = "0.10" diff --git a/examples/inner_html/Cargo.toml b/examples/inner_html/Cargo.toml index 345860ef7bb..9b9a12047bc 100644 --- a/examples/inner_html/Cargo.toml +++ b/examples/inner_html/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] yew = { path = "../../packages/yew", features = ["csr"] } -gloo = "0.8" +gloo = "0.10" [dependencies.web-sys] version = "0.3" diff --git a/examples/keyed_list/Cargo.toml b/examples/keyed_list/Cargo.toml index 2dd60c5789d..3273faed3c4 100644 --- a/examples/keyed_list/Cargo.toml +++ b/examples/keyed_list/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" license = "MIT OR Apache-2.0" [dependencies] -fake = "2.6.1" +fake = "2.8.0" getrandom = { version = "0.2", features = ["js"] } instant = { version = "0.1", features = ["wasm-bindgen"] } log = "0.4" diff --git a/examples/mount_point/Cargo.toml b/examples/mount_point/Cargo.toml index cacd672df83..d33af38f6ee 100644 --- a/examples/mount_point/Cargo.toml +++ b/examples/mount_point/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" [dependencies] wasm-bindgen = "0.2" yew = { path = "../../packages/yew", features = ["csr"] } -gloo = "0.8" +gloo = "0.10" [dependencies.web-sys] version = "0.3" diff --git a/examples/password_strength/Cargo.toml b/examples/password_strength/Cargo.toml index 2e832429346..b4798e01bea 100644 --- a/examples/password_strength/Cargo.toml +++ b/examples/password_strength/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] yew = { path = "../../packages/yew", features = ["csr"] } zxcvbn = "2.2.2" -time = "0.3.22" +time = "0.3.28" js-sys = "0.3.64" web-sys = { version = "0.3", features = ["Event","EventTarget","InputEvent"] } wasm-bindgen = "0.2" diff --git a/examples/portals/Cargo.toml b/examples/portals/Cargo.toml index 00aa66823d9..a7b04290582 100644 --- a/examples/portals/Cargo.toml +++ b/examples/portals/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] yew = { path = "../../packages/yew", features = ["csr"] } -gloo = "0.8" +gloo = "0.10" wasm-bindgen = "0.2" [dependencies.web-sys] diff --git a/examples/router/Cargo.toml b/examples/router/Cargo.toml index f6b8e6d9bca..9c21071b012 100644 --- a/examples/router/Cargo.toml +++ b/examples/router/Cargo.toml @@ -15,4 +15,4 @@ yew = { path = "../../packages/yew", features = ["csr"] } yew-router = { path = "../../packages/yew-router" } serde = { version = "1.0", features = ["derive"] } once_cell = "1" -gloo = "0.8" +gloo = "0.10" diff --git a/examples/simple_ssr/Cargo.toml b/examples/simple_ssr/Cargo.toml index 0a27c870458..0aaed6f6bc2 100644 --- a/examples/simple_ssr/Cargo.toml +++ b/examples/simple_ssr/Cargo.toml @@ -14,11 +14,11 @@ required-features = ["ssr"] [dependencies] yew = { path = "../../packages/yew" } -reqwest = { version = "0.11.18", features = ["json"] } -serde = { version = "1.0.164", features = ["derive"] } -uuid = { version = "1.4.0", features = ["serde"] } +reqwest = { version = "0.11.20", features = ["json"] } +serde = { version = "1.0.188", features = ["derive"] } +uuid = { version = "1.4.1", features = ["serde"] } futures = "0.3" -bytes = "1.4" +bytes = "1.5" [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen-futures = "0.4" @@ -26,7 +26,7 @@ wasm-logger = "0.2" log = "0.4" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -tokio = { version = "1.29.0", features = ["full"] } +tokio = { version = "1.32.0", features = ["full"] } warp = "0.3" clap = { version = "4", features = ["derive"] } diff --git a/examples/ssr_router/Cargo.toml b/examples/ssr_router/Cargo.toml index a3300cc4e1d..86f598cbf86 100644 --- a/examples/ssr_router/Cargo.toml +++ b/examples/ssr_router/Cargo.toml @@ -24,7 +24,7 @@ wasm-bindgen-futures = "0.4" wasm-logger = "0.2" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -tokio = { version = "1.29.0", features = ["full"] } +tokio = { version = "1.32.0", features = ["full"] } axum = "0.6" tower = { version = "0.4", features = ["make"] } tower-http = { version = "0.3", features = ["fs"] } diff --git a/examples/suspense/Cargo.toml b/examples/suspense/Cargo.toml index 389bd4b19ba..170984be100 100644 --- a/examples/suspense/Cargo.toml +++ b/examples/suspense/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" [dependencies] yew = { path = "../../packages/yew", features = ["csr"] } -gloo = { version = "0.8", features = ["futures"] } +gloo = { version = "0.10", features = ["futures"] } wasm-bindgen-futures = "0.4" wasm-bindgen = "0.2" diff --git a/examples/timer/Cargo.toml b/examples/timer/Cargo.toml index 3a3a3b30dbf..d8e3545e4e4 100644 --- a/examples/timer/Cargo.toml +++ b/examples/timer/Cargo.toml @@ -8,5 +8,5 @@ license = "MIT OR Apache-2.0" [dependencies] yew = { path = "../../packages/yew", features = ["csr"] } js-sys = "0.3" -gloo = "0.8" +gloo = "0.10" wasm-bindgen = "0.2" diff --git a/examples/timer_functional/Cargo.toml b/examples/timer_functional/Cargo.toml index 3d0c36b56de..aaa13975bf2 100644 --- a/examples/timer_functional/Cargo.toml +++ b/examples/timer_functional/Cargo.toml @@ -6,6 +6,6 @@ edition = "2021" license = "MIT OR Apache-2.0" [dependencies] -gloo = "0.8.1" +gloo = "0.10.0" js-sys = "0.3.64" yew = { path = "../../packages/yew", features = ["csr"] } diff --git a/examples/todomvc/Cargo.toml b/examples/todomvc/Cargo.toml index 10f64d9c36d..dfb83760194 100644 --- a/examples/todomvc/Cargo.toml +++ b/examples/todomvc/Cargo.toml @@ -11,7 +11,7 @@ strum_macros = "0.25" serde = "1" serde_derive = "1" yew = { path = "../../packages/yew", features = ["csr"] } -gloo = "0.8" +gloo = "0.10" [dependencies.web-sys] version = "0.3" diff --git a/examples/two_apps/Cargo.toml b/examples/two_apps/Cargo.toml index 9797f473743..01fa89c05d3 100644 --- a/examples/two_apps/Cargo.toml +++ b/examples/two_apps/Cargo.toml @@ -7,4 +7,4 @@ license = "MIT OR Apache-2.0" [dependencies] yew = { path = "../../packages/yew", features = ["csr"] } -gloo = "0.8" +gloo = "0.10" diff --git a/examples/web_worker_fib/Cargo.toml b/examples/web_worker_fib/Cargo.toml index 31b7f09b8dc..8a428c5ee1d 100644 --- a/examples/web_worker_fib/Cargo.toml +++ b/examples/web_worker_fib/Cargo.toml @@ -11,4 +11,4 @@ wasm-bindgen = "0.2" js-sys = "0.3" web-sys = { version = "0.3", features = [ "HtmlInputElement" ] } serde = { version = "1", features = ["derive"] } -postcard = "1.0.0" +postcard = "1.0.7" diff --git a/examples/web_worker_prime/Cargo.toml b/examples/web_worker_prime/Cargo.toml index b66142ba89b..89076dfa7ff 100644 --- a/examples/web_worker_prime/Cargo.toml +++ b/examples/web_worker_prime/Cargo.toml @@ -8,4 +8,4 @@ yew-agent = { path = "../../packages/yew-agent" } yew = { path = "../../packages/yew", features = ["csr"] } futures = "0.3.25" primes = "0.3.0" -serde = { version = "1.0.147", features = ["derive"] } +serde = { version = "1.0.188", features = ["derive"] } diff --git a/packages/yew-agent/Cargo.toml b/packages/yew-agent/Cargo.toml index 9bfe65c1d9f..fd492a41fb1 100644 --- a/packages/yew-agent/Cargo.toml +++ b/packages/yew-agent/Cargo.toml @@ -13,11 +13,11 @@ rust-version = "1.64.0" [dependencies] yew = { version = "0.20.0", path = "../yew" } -gloo-worker = { version = "0.3", features = ["futures"] } +gloo-worker = { version = "0.4", features = ["futures"] } wasm-bindgen = "0.2" serde = { version = "1", features = ["derive"] } futures = "0.3" yew-agent-macro = { version = "0.1", path = "../yew-agent-macro" } [dev-dependencies] -serde = "1.0.164" +serde = "1.0.188" diff --git a/packages/yew-macro/tests/derive_props/fail.stderr b/packages/yew-macro/tests/derive_props/fail.stderr index 881609aeaf9..e3d2c5461ff 100644 --- a/packages/yew-macro/tests/derive_props/fail.stderr +++ b/packages/yew-macro/tests/derive_props/fail.stderr @@ -1,4 +1,4 @@ -error: unexpected end of input, expected expression +error: unexpected end of input, expected an expression --> tests/derive_props/fail.rs:56:19 | 56 | #[prop_or()] diff --git a/packages/yew-macro/tests/html_macro/component-fail.stderr b/packages/yew-macro/tests/html_macro/component-fail.stderr index 371362c18bc..6280ac8d37b 100644 --- a/packages/yew-macro/tests/html_macro/component-fail.stderr +++ b/packages/yew-macro/tests/html_macro/component-fail.stderr @@ -22,7 +22,7 @@ error: expected base props expression after `..` 46 | html! { }; | ^^ -error: unexpected end of input, expected expression +error: unexpected end of input, expected an expression --> tests/html_macro/component-fail.rs:46:13 | 46 | html! { }; @@ -34,7 +34,7 @@ error: expected base props expression after `..` 47 | html! { }; | ^^ -error: unexpected end of input, expected expression +error: unexpected end of input, expected an expression --> tests/html_macro/component-fail.rs:47:28 | 47 | html! { }; diff --git a/packages/yew-router/Cargo.toml b/packages/yew-router/Cargo.toml index f867ff0ae77..7d5e336fa2c 100644 --- a/packages/yew-router/Cargo.toml +++ b/packages/yew-router/Cargo.toml @@ -17,12 +17,12 @@ yew-router-macro = { version = "0.17.0", path = "../yew-router-macro" } wasm-bindgen = "0.2" js-sys = "0.3" -gloo = { version = "0.8", features = ["futures"] } +gloo = { version = "0.10", features = ["futures"] } route-recognizer = "0.3" serde = "1" serde_urlencoded = "0.7.1" tracing = "0.1.37" -urlencoding = "2.1.2" +urlencoding = "2.1.3" [dependencies.web-sys] version = "0.3" diff --git a/packages/yew/Cargo.toml b/packages/yew/Cargo.toml index f84c3d8279e..075046da6bb 100644 --- a/packages/yew/Cargo.toml +++ b/packages/yew/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.64.0" [dependencies] console_error_panic_hook = "0.1" -gloo = "0.8" +gloo = "0.10" indexmap = { version = "2", features = ["std"] } js-sys = "0.3" slab = "0.4" @@ -27,7 +27,7 @@ yew-macro = { version = "^0.20.0", path = "../yew-macro" } thiserror = "1.0" futures = { version = "0.3", default-features = false, features = ["std"] } html-escape = { version = "0.2.13", optional = true } -implicit-clone = { version = "0.4.0", features = ["map"] } +implicit-clone = { version = "0.4.1", features = ["map"] } base64ct = { version = "1.6.0", features = ["std"], optional = true } bincode = { version = "1.3.3", optional = true } serde = { version = "1", features = ["derive"] } @@ -40,7 +40,7 @@ wasm-bindgen-futures = "0.4" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] # We still need tokio as we have docs linked to it. -tokio = { version = "1.29", features = ["rt"] } +tokio = { version = "1.32", features = ["rt"] } [dependencies.web-sys] version = "^0.3.64" @@ -79,11 +79,11 @@ features = [ ] [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] -tokio = { version = "1.29", features = ["full"] } +tokio = { version = "1.32", features = ["full"] } [dev-dependencies] wasm-bindgen-test = "0.3" -gloo = { version = "0.8", features = ["futures"] } +gloo = { version = "0.10", features = ["futures"] } wasm-bindgen-futures = "0.4" trybuild = "1" diff --git a/tools/benchmark-ssr/Cargo.toml b/tools/benchmark-ssr/Cargo.toml index e190d1b3fdb..5915ae89128 100644 --- a/tools/benchmark-ssr/Cargo.toml +++ b/tools/benchmark-ssr/Cargo.toml @@ -8,11 +8,11 @@ edition = "2021" [dependencies] yew = { path = "../../packages/yew", features = ["ssr"] } function_router = { path = "../../examples/function_router" } -tokio = { version = "1.29", features = ["full"] } -jemallocator = "0.5.0" -average = "0.13.1" -tabled = "0.12.2" -indicatif = "0.17.5" -serde = { version = "1.0.164", features = ["derive"] } -serde_json = "1.0.104" +tokio = { version = "1.32", features = ["full"] } +jemallocator = "0.5.4" +average = "0.14.1" +tabled = "0.14.0" +indicatif = "0.17.6" +serde = { version = "1.0.188", features = ["derive"] } +serde_json = "1.0.107" clap = { version = "4", features = ["derive"] } diff --git a/tools/changelog/Cargo.toml b/tools/changelog/Cargo.toml index 03c9bd110d4..a5bc3bb9357 100644 --- a/tools/changelog/Cargo.toml +++ b/tools/changelog/Cargo.toml @@ -9,7 +9,7 @@ edition = "2021" [dependencies] anyhow = "1" chrono = "0.4" -git2 = "0.17" +git2 = "0.18" regex = "1" reqwest = { version = "0.11", features = ["blocking", "json"] } serde = { version = "1", features = ["derive"] } diff --git a/tools/website-test/Cargo.toml b/tools/website-test/Cargo.toml index f6f61e59ae9..ca0233f99b6 100644 --- a/tools/website-test/Cargo.toml +++ b/tools/website-test/Cargo.toml @@ -12,14 +12,14 @@ yew-agent = { path = "../../packages/yew-agent/" } [dev-dependencies] boolinator = "2.4" derive_more = "0.99" -gloo = "0.8" +gloo = "0.10" js-sys = "0.3" wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" weblog = "0.3.0" yew = { path = "../../packages/yew/", features = ["ssr", "csr"] } yew-router = { path = "../../packages/yew-router/" } -tokio = { version = "1.29.0", features = ["rt", "macros"] } +tokio = { version = "1.32.0", features = ["rt", "macros"] } [dev-dependencies.web-sys] version = "0.3" From 0f2fc59b543eb9c3cab9b498208d787b5cce8107 Mon Sep 17 00:00:00 2001 From: Tim Kurdov Date: Sat, 23 Sep 2023 14:02:44 +0100 Subject: [PATCH 10/14] Updated the docs of `set_event_bubbling` (#3391) The removed paragraph describes a caveat of the framework which is no longer true --- packages/yew/src/dom_bundle/subtree_root.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/yew/src/dom_bundle/subtree_root.rs b/packages/yew/src/dom_bundle/subtree_root.rs index 0a9f4954bae..83720fecddf 100644 --- a/packages/yew/src/dom_bundle/subtree_root.rs +++ b/packages/yew/src/dom_bundle/subtree_root.rs @@ -286,10 +286,6 @@ static BUBBLE_EVENTS: AtomicBool = AtomicBool::new(true); /// Bubbling is enabled by default. Disabling bubbling can lead to substantial improvements in event /// handling performance. /// -/// Note that yew uses event delegation and implements internal even bubbling for performance -/// reasons. Calling `Event.stopPropagation()` or `Event.stopImmediatePropagation()` in the event -/// handler has no effect. -/// /// This function should be called before any component is mounted. #[cfg(feature = "csr")] pub fn set_event_bubbling(bubble: bool) { From 0c802f80ea335222721ff05d8f7ef1aaf2e7ef4b Mon Sep 17 00:00:00 2001 From: Imbus <66123528+imbus64@users.noreply.github.com> Date: Sat, 23 Sep 2023 15:03:48 +0200 Subject: [PATCH 11/14] Documentation changes related to context code snippets (#3396) --- website/versioned_docs/version-0.20/concepts/contexts.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/versioned_docs/version-0.20/concepts/contexts.mdx b/website/versioned_docs/version-0.20/concepts/contexts.mdx index f004c454875..27c72ca351e 100644 --- a/website/versioned_docs/version-0.20/concepts/contexts.mdx +++ b/website/versioned_docs/version-0.20/concepts/contexts.mdx @@ -107,7 +107,7 @@ struct Theme { #[function_component] fn NavButton() -> Html { - let theme = use_context::(); + let theme = use_context::>().expect("Context not found"); html! { // use theme From 5bab22da4a4386fa57182e9e7774ebdd2422661c Mon Sep 17 00:00:00 2001 From: RazaGR <30994076+RazaGR@users.noreply.github.com> Date: Sat, 23 Sep 2023 15:15:40 +0200 Subject: [PATCH 12/14] Add neovim configuration to docs (#3400) * add neovim configuration doc add neovim configuration documentation to setup with lazy.vim plugin. * prettier --------- Co-authored-by: Muhammad Hamza --- website/docs/getting-started/editor-setup.mdx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/website/docs/getting-started/editor-setup.mdx b/website/docs/getting-started/editor-setup.mdx index c97a38a7f47..241d12e5f60 100644 --- a/website/docs/getting-started/editor-setup.mdx +++ b/website/docs/getting-started/editor-setup.mdx @@ -137,3 +137,24 @@ Emmet support should work out of the box, if not please fall back to edditing th "rust": "html", } ``` + +### Neovim + +#### Lazyvim + +> Below configuration works with [LazyVim](https://www.lazyvim.org) configuration and lazy.vim plugin, create a file in `lua/plugins/nvim-lspconfig.lua` (or update your `lspconfig`) with: + +```json +return { + { + "neovim/nvim-lspconfig", + init_options = { + userLanguages = { + eelixir = "html-eex", + eruby = "erb", + rust = "html", + }, + }, + }, +} +``` From 189a7296d14d2d64a5dc1e12566c263608d430dd Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Sat, 23 Sep 2023 18:20:54 +0500 Subject: [PATCH 13/14] Remove unneded package-lock.json (#3411) --- package-lock.json | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 1c67da3f6cc..00000000000 --- a/package-lock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "yew", - "lockfileVersion": 3, - "requires": true, - "packages": {} -} From 30e2d548ef57a4b738fb285251b986467ef7eb95 Mon Sep 17 00:00:00 2001 From: Tim Kurdov Date: Sat, 23 Sep 2023 15:00:35 +0100 Subject: [PATCH 14/14] Added a note about using suspension (#3410) * added a note about implementing suspending hooks * fixed formatting * extracted part of the note into a danger block * added ::: * added spaces --- website/docs/concepts/suspense.mdx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/website/docs/concepts/suspense.mdx b/website/docs/concepts/suspense.mdx index 6c697d82f00..efd8d1e566c 100644 --- a/website/docs/concepts/suspense.mdx +++ b/website/docs/concepts/suspense.mdx @@ -78,6 +78,23 @@ fn use_user() -> SuspensionResult { } ``` +#### Note on implementing suspending hooks + +[`Suspension::new`](https://docs.rs/yew/latest/yew/suspense/struct.Suspension.html#method.new) returns 2 values: the suspension context itself, and a suspension handle. +The latter is the one responsible for signaling when to re-render the suspended components, it provides 2 interchangable ways to do so: + +1. Calling its [`resume`](https://docs.rs/yew/latest/yew/suspense/struct.SuspensionHandle.html#method.resume) method. +2. Dropping the handle. + +:::danger + +The suspension handle must be stored until it's time to update components, i.e. with newly received data; +otherwise, the suspended components will enter an infinite re-render loop, thus hampering performance. +In the example above, the suspension handle is preserved by being moved into a closure and passed into `on_load_user_complete`. +When the hypothetical user will be loaded, the closure will be called, thus calling `handle.resume()` and re-rendering the components associated with the suspension context. + +::: + # Complete Example ```rust