diff --git a/examples/agents/src/bin/worker.rs b/examples/agents/src/bin/worker.rs index bf82bb5eb..c9febfed6 100644 --- a/examples/agents/src/bin/worker.rs +++ b/examples/agents/src/bin/worker.rs @@ -1,5 +1,5 @@ use agents::native_worker::Worker; -use yew_agent::Threaded; +use yew_agent::PublicAgent; fn main() { wasm_logger::init(wasm_logger::Config::default()); diff --git a/examples/web_worker_fib/src/lib.rs b/examples/web_worker_fib/src/lib.rs index 16c37a051..3832440df 100644 --- a/examples/web_worker_fib/src/lib.rs +++ b/examples/web_worker_fib/src/lib.rs @@ -5,7 +5,7 @@ pub mod agent; pub mod app; use app::Model; use wasm_bindgen::prelude::*; -use yew_agent::Threaded; +use yew_agent::PublicAgent; #[wasm_bindgen(start)] pub fn start() { diff --git a/packages/yew-agent/src/lib.rs b/packages/yew-agent/src/lib.rs index 54c6ab3c9..1c44060aa 100644 --- a/packages/yew-agent/src/lib.rs +++ b/packages/yew-agent/src/lib.rs @@ -1,4 +1,4 @@ -//! This module contains types to support multi-threading and state management. +//! This module contains Yew's web worker implementation. mod hooks; mod link; @@ -10,7 +10,7 @@ pub use link::AgentLink; pub(crate) use link::*; pub(crate) use pool::*; pub use pool::{Dispatched, Dispatcher}; -pub use worker::{Private, Public, Threaded}; +pub use worker::{Private, PrivateAgent, Public, PublicAgent}; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/packages/yew-agent/src/worker/mod.rs b/packages/yew-agent/src/worker/mod.rs index ad97978d9..392027778 100644 --- a/packages/yew-agent/src/worker/mod.rs +++ b/packages/yew-agent/src/worker/mod.rs @@ -2,8 +2,8 @@ mod private; mod public; mod queue; -pub use private::Private; -pub use public::Public; +pub use private::{Private, PrivateAgent}; +pub use public::{Public, PublicAgent}; use super::*; use js_sys::{Array, Reflect, Uint8Array}; @@ -13,11 +13,19 @@ use web_sys::{ Blob, BlobPropertyBag, DedicatedWorkerGlobalScope, MessageEvent, Url, Worker, WorkerOptions, }; -/// Implements rules to register a worker in a separate thread. -pub trait Threaded { - /// Executes an agent in the current environment. - /// Uses in `main` function of a worker. - fn register(); +pub(crate) struct WorkerResponder {} + +impl Responder for WorkerResponder +where + AGN: Agent, + ::Input: Serialize + for<'de> Deserialize<'de>, + ::Output: Serialize + for<'de> Deserialize<'de>, +{ + fn respond(&self, id: HandlerId, output: AGN::Output) { + let msg = FromWorker::ProcessOutput(id, output); + let data = msg.pack(); + worker_self().post_message_vec(data); + } } /// Message packager, based on serde::Serialize/Deserialize diff --git a/packages/yew-agent/src/worker/private.rs b/packages/yew-agent/src/worker/private.rs index ba4380a5c..45a6bb327 100644 --- a/packages/yew-agent/src/worker/private.rs +++ b/packages/yew-agent/src/worker/private.rs @@ -21,6 +21,56 @@ pub struct Private { _agent: PhantomData, } +/// A trait to enable private agents being registered in a web worker. +pub trait PrivateAgent { + /// Executes an agent in the current environment. + /// Uses in `main` function of a worker. + fn register(); +} + +impl PrivateAgent for AGN +where + AGN: Agent>, + ::Input: Serialize + for<'de> Deserialize<'de>, + ::Output: Serialize + for<'de> Deserialize<'de>, +{ + fn register() { + let scope = AgentScope::::new(); + let responder = WorkerResponder {}; + let link = AgentLink::connect(&scope, responder); + let upd = AgentLifecycleEvent::Create(link); + scope.send(upd); + let handler = move |data: Vec| { + let msg = ToWorker::::unpack(&data); + match msg { + ToWorker::Connected(_id) => { + let upd = AgentLifecycleEvent::Connected(SINGLETON_ID); + scope.send(upd); + } + ToWorker::ProcessInput(_id, value) => { + let upd = AgentLifecycleEvent::Input(value, SINGLETON_ID); + scope.send(upd); + } + ToWorker::Disconnected(_id) => { + let upd = AgentLifecycleEvent::Disconnected(SINGLETON_ID); + scope.send(upd); + } + ToWorker::Destroy => { + let upd = AgentLifecycleEvent::Destroy; + scope.send(upd); + // Terminates web worker + worker_self().close(); + } + } + }; + let loaded: FromWorker = FromWorker::WorkerLoaded; + let loaded = loaded.pack(); + let worker = worker_self(); + worker.set_onmessage_closure(handler); + worker.post_message_vec(loaded); + } +} + impl Discoverer for Private where AGN: Agent, diff --git a/packages/yew-agent/src/worker/public.rs b/packages/yew-agent/src/worker/public.rs index 1f7d94e39..7379ec198 100644 --- a/packages/yew-agent/src/worker/public.rs +++ b/packages/yew-agent/src/worker/public.rs @@ -181,22 +181,14 @@ where } } -struct WorkerResponder {} - -impl Responder for WorkerResponder -where - AGN: Agent, - ::Input: Serialize + for<'de> Deserialize<'de>, - ::Output: Serialize + for<'de> Deserialize<'de>, -{ - fn respond(&self, id: HandlerId, output: AGN::Output) { - let msg = FromWorker::ProcessOutput(id, output); - let data = msg.pack(); - worker_self().post_message_vec(data); - } +/// A trait to enable public agents being registered in a web worker. +pub trait PublicAgent { + /// Executes an agent in the current environment. + /// Uses in `main` function of a worker. + fn register(); } -impl Threaded for AGN +impl PublicAgent for AGN where AGN: Agent>, ::Input: Serialize + for<'de> Deserialize<'de>, diff --git a/website/docs/concepts/agents.mdx b/website/docs/concepts/agents.mdx index 33500ae20..a996f3b66 100644 --- a/website/docs/concepts/agents.mdx +++ b/website/docs/concepts/agents.mdx @@ -36,8 +36,8 @@ The code can be found in the tag of the svgs. When no bridges are connected to this agent, the agent will disappear. * Private - Spawn a new agent in a web worker for every new bridge. This is good for moving shared but - independent behavior that communicates with the browser out of components. \(TODO verify\) When - the task is done, the agent will disappear. + independent behavior that communicates with the browser out of components. When + the the connected bridge is dropped, the agent will disappear. * Global \(WIP\) diff --git a/website/docs/migration-guides/yew-agent/from-0_1_0-to-0_2_0.mdx b/website/docs/migration-guides/yew-agent/from-0_1_0-to-0_2_0.mdx index d32fdd709..ba736b6ad 100644 --- a/website/docs/migration-guides/yew-agent/from-0_1_0-to-0_2_0.mdx +++ b/website/docs/migration-guides/yew-agent/from-0_1_0-to-0_2_0.mdx @@ -2,8 +2,21 @@ title: "From 0.1.0 to 0.2.0" --- +## Removal of `Context` and `Job` Agents + The `Context` and `Job` Agents have been removed in favour of Yew's Context API. You can see the updated [`pub_sub`](https://github.com/yewstack/yew/tree/master/examples/pub_sub) example about how to use Context API. For users of `yew_agent::utils::store`, you may switch to third party solutions like: [Yewdux](https://github.com/intendednull/yewdux) or [Bounce](https://github.com/futursolo/bounce). + +## `Threaded` is separated into `PublicAgent` and `PrivateAgent` + +Replace `use yew_agent::Threaded;` with `use yew_agent::PublicAgent;`. + +:::note + +`Threaded` was never implemented for Private Agents. +All existing web worker-based agents are Public Agents. + +:::