Expand description
Ergonomic Comlink RPC for
Rust and WebAssembly: define a service as a trait, annotate it with
service, and the macro generates a client and a service that speak
comlink’s protocol over any endpoint (a Worker, a MessagePort, a window
endpoint).
#[comlink::service]
pub trait Calculator {
async fn add(&self, left: u32, right: u32) -> u32;
}The macro emits CalculatorClient::wrap(&endpoint) for the calling side and
CalculatorService::expose(implementation, &endpoint) for the serving side.
Arguments and return values cross as structured clones: JsValue-bearing
types untouched, byte buffers as Uint8Array (Option<Vec<u8>> as
Uint8Array or undefined), everything else through serde. A method
returning Result maps onto the promise: Ok resolves with the encoded
value, Err rejects with the encoded error, so a JavaScript peer just
returns or throws. Every rejection decodes into the error type, a thrown
Error first reduced to its message, so keep that type a serde one such
as String. A remote panic or a released proxy arrives the same way, as an
Err rather than the panic a non-Result method raises.
The raw bindings this is built on are re-exported as sys, for the parts
of comlink the macro does not cover. The npm comlink package has to be
resolvable by whatever bundler or module loader serves the generated
JavaScript.
Re-exports§
pub use comlink_sys as sys;pub use futures;
Modules§
- client
- The calling side of a generated client. Everything here but
StreamReceiverexists for the code#[comlink::service]emits. A method returningResulttakes itsOkfrom the promise’s resolution and itsErrfrom the rejection. - ready
- Comlink has no handshake, so a request posted before the remote’s expose listener attaches is lost. The serving side announces readiness with a sentinel once exposed; both comlink listeners ignore it (no type, no id).