Skip to main content

web_rpc/
port.rs

1use wasm_bindgen::JsValue;
2
3/// The Javascript types that send and receive messages.
4///
5/// A port is a transport that web-rpc is handed, never one that it owns: each variant is a
6/// cheap handle to a Javascript object, and dropping the last clone does nothing.
7///
8/// - Nothing here terminates a [`web_sys::Worker`]. Whoever created the worker terminates it.
9/// - Nothing here calls [`web_sys::MessagePort::start`]. **A `MessagePort` must be started by
10///   its owner before it is handed over**, otherwise it delivers nothing to the listener that
11///   [`crate::Interface::new`] installs and the handshake never completes.
12#[derive(Clone)]
13pub enum Port {
14    Worker(web_sys::Worker),
15    DedicatedWorkerGlobalScope(web_sys::DedicatedWorkerGlobalScope),
16    MessagePort(web_sys::MessagePort),
17}
18
19impl Port {
20    /// Post a message with a transfer list.
21    pub fn post_message(&self, message: &JsValue, transfer: &JsValue) -> Result<(), JsValue> {
22        match self {
23            Port::Worker(worker) => worker.post_message_with_transfer(message, transfer),
24            Port::DedicatedWorkerGlobalScope(scope) => {
25                scope.post_message_with_transfer(message, transfer)
26            }
27            Port::MessagePort(port) => port.post_message_with_transferable(message, transfer),
28        }
29    }
30
31    pub(crate) fn event_target(&self) -> &web_sys::EventTarget {
32        match self {
33            Port::Worker(worker) => worker.as_ref(),
34            Port::DedicatedWorkerGlobalScope(scope) => scope.as_ref(),
35            Port::MessagePort(port) => port.as_ref(),
36        }
37    }
38}
39
40impl From<web_sys::Worker> for Port {
41    fn from(worker: web_sys::Worker) -> Self {
42        Port::Worker(worker)
43    }
44}
45
46impl From<web_sys::DedicatedWorkerGlobalScope> for Port {
47    fn from(scope: web_sys::DedicatedWorkerGlobalScope) -> Self {
48        Port::DedicatedWorkerGlobalScope(scope)
49    }
50}
51
52impl From<web_sys::MessagePort> for Port {
53    fn from(port: web_sys::MessagePort) -> Self {
54        Port::MessagePort(port)
55    }
56}