1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#![allow(clippy::new_without_default)]
#![allow(clippy::or_fun_call)]
//! # Features
//! ## `d1`
//!
//! Allows the use of [D1 bindings](crate::d1) and [`query!`](crate::query) macro.
//!
//!
//! ## `queue`
//!
//! Enables `queue` event type in [`[event]`](worker_macros::event) macro.
//!
//! ```
//! // Consume messages from a queue
//! #[event(queue)]
//! pub async fn main(message_batch: MessageBatch<MyType>, env: Env, _ctx: Context) -> Result<()> {
//!     Ok(())
//! }
//! ```
//!
//! ## `http`
//! `worker` `0.0.21` introduced an `http` feature flag which starts to replace custom types with widely used types from the [`http`](https://docs.rs/http/latest/http/) crate.
//!
//! This makes it much easier to use crates which use these standard types such as [`axum`].
//!
//! This currently does a few things:
//!
//! 1. Introduce [`Body`], which implements [`http_body::Body`] and is a simple wrapper around [`web_sys::ReadableStream`].
//! 1. The `req` argument when using the [`[event(fetch)]`](worker_macros::event) macro becomes `http::Request<worker::Body>`.
//! 1. The expected return type for the fetch handler is `http::Response<B>` where `B` can be any [`http_body::Body<Data=Bytes>`](http_body::Body).
//! 1. The argument for [`Fetcher::fetch_request`](Fetcher::fetch_request) is `http::Request<worker::Body>`.
//! 1. The return type of [`Fetcher::fetch_request`](Fetcher::fetch_request) is `http::Response<worker::Body>`.
//!
//! The end result is being able to use frameworks like `axum` directly (see [example](./examples/axum)):
//!
//! ```rust
//! pub async fn root() -> &'static str {
//!     "Hello Axum!"
//! }
//!
//! fn router() -> Router {
//!     Router::new().route("/", get(root))
//! }
//!
//! #[event(fetch)]
//! async fn fetch(
//!     req: HttpRequest,
//!     _env: Env,
//!     _ctx: Context,
//! ) -> Result<http::Response<axum::body::Body>> {
//!     Ok(router().call(req).await?)
//! }
//! ```
//!
//! We also implement `try_from` between `worker::Request` and `http::Request<worker::Body>`, and between `worker::Response` and `http::Response<worker::Body>`.
//! This allows you to convert your code incrementally if it is tightly coupled to the original types.
//!
//! ### `Send` Helpers
//!
//! A number of frameworks (including `axum`) require that objects that they are given (including route handlers) can be
//! sent between threads (i.e are marked as `Send`). Unfortuntately, objects which interact with JavaScript are frequently
//! not marked as `Send`. In the Workers environment, this is not an issue, because Workers are single threaded. There are still
//! some ergonomic difficulties which we address with some wrapper types:
//!
//! 1. [`send::SendFuture`] - wraps any `Future` and marks it as `Send`:
//!
//! ```rust
//! // `fut` is `Send`
//! let fut = send::SendFuture::new(async move {
//!     // `JsFuture` is not `Send`
//!     JsFuture::from(promise).await
//! });
//! ```
//!
//! 2. [`send::SendWrapper`] - Marks an arbitrary object as `Send` and implements `Deref` and `DerefMut`, as well as `Clone`, `Debug`, and `Display` if the
//!    inner type does. This is useful for attaching types as state to an `axum` `Router`:
//!
//! ```rust
//! // `KvStore` is not `Send`
//! let store = env.kv("FOO")?;
//! // `state` is `Send`
//! let state = send::SendWrapper::new(store);
//! let router = axum::Router::new()
//!     .layer(Extension(state));
//! ```
//!
//! 3. [`[worker::send]`](macro@crate::send) - Macro to make any `async` function `Send`. This can be a little tricky to identify as the problem, but
//!    `axum`'s `[debug_handler]` macro can help, and looking for warnings that a function or object cannot safely be sent
//!    between threads.
//!
//! ```rust
//! // This macro makes the whole function (i.e. the `Future` it returns) `Send`.
//! #[worker::send]
//! async fn handler(Extension(env): Extension<Env>) -> Response<String> {
//!     let kv = env.kv("FOO").unwrap()?;
//!     // Holding `kv`, which is not `Send` across `await` boundary would mark this function as `!Send`
//!     let value = kv.get("foo").text().await?;
//!     Ok(format!("Got value: {:?}", value));
//! }
//!
//! let router = axum::Router::new()
//!     .route("/", get(handler))
//! ```
//!
//! # RPC Support
//! `workers-rs` has experimental support for [Workers RPC](https://developers.cloudflare.com/workers/runtime-apis/rpc/).
//! For now, this relies on JavaScript bindings and may require some manual usage of `wasm-bindgen`.
//!
//! Not all features of RPC are supported yet (or have not been tested), including:
//! - Function arguments and return values
//! - Class instances
//! - Stub forwarding
//!
//! ## RPC Server
//!
//! Writing an RPC server with `workers-rs` is relatively simple. Simply export methods using `wasm-bindgen`. These
//! will be automatically detected by `worker-build` and made available to other Workers. See
//! [example](https://github.com/cloudflare/workers-rs/tree/main/examples/rpc-server).
//!
//! ## RPC Client
//!
//! Creating types and bindings for invoking another Worker's RPC methods is a bit more involved. You will need to
//! write more complex `wasm-bindgen` bindings and some boilerplate to make interacting with the RPC methods more
//! idiomatic. See [example](https://github.com/cloudflare/workers-rs/blob/main/examples/rpc-client/src/calculator.rs).
//!
//! With manually written bindings, it should be possible to support non-primitive argument and return types, using
//! `serde-wasm-bindgen`.
//!
//! ## Generating Client Bindings
//!
//! There are many routes that can be taken to describe RPC interfaces. Under the hood, Workers RPC uses
//! [Cap'N Proto](https://capnproto.org/). A possible future direction is for Wasm guests to include Cap'N Proto
//! serde support and speak directly to the RPC protocol, bypassing JavaScript. This would likely involve defining
//! the RPC interface in Cap'N Proto schema and generating Rust code from that.
//!
//! Another popular interface schema in the WebAssembly community is
//! [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md). This is a lightweight format
//! designed for the WebAssembly Component model. `workers-rs` includes an **experimental** code generator which
//! allows you to describe your RPC interface using WIT and generate JavaScript bindings as shown in the
//! [rpc-client example](https://github.com/cloudflare/workers-rs/blob/main/examples/rpc-client/wit/calculator.wit).
//! The easiest way to use this code generator is using a
//! [build script](https://github.com/cloudflare/workers-rs/blob/main/examples/rpc-client/build.rs) as shown in the example.
//! This code generator is pre-alpha, with no support guarantee, and implemented only for primitive types at this time.

#[doc(hidden)]
use std::result::Result as StdResult;

#[doc(hidden)]
pub use async_trait;
#[doc(hidden)]
pub use js_sys;
pub use url::Url;
#[doc(hidden)]
pub use wasm_bindgen;
#[doc(hidden)]
pub use wasm_bindgen_futures;
pub use worker_kv as kv;

pub use cf::{Cf, TlsClientAuth};
pub use worker_macros::{durable_object, event, send};
#[doc(hidden)]
pub use worker_sys;
pub use worker_sys::{console_debug, console_error, console_log, console_warn};

pub use crate::abort::*;
pub use crate::cache::{Cache, CacheDeletionOutcome, CacheKey};
pub use crate::context::Context;
pub use crate::cors::Cors;
#[cfg(feature = "d1")]
pub use crate::d1::*;
pub use crate::date::{Date, DateInit};
pub use crate::delay::Delay;
pub use crate::durable::*;
pub use crate::dynamic_dispatch::*;
pub use crate::env::{Env, EnvBinding, Secret, Var};
pub use crate::error::Error;
pub use crate::fetcher::Fetcher;
pub use crate::formdata::*;
pub use crate::global::Fetch;
pub use crate::headers::Headers;
pub use crate::http::Method;
#[cfg(feature = "queue")]
pub use crate::queue::*;
pub use crate::r2::*;
pub use crate::request::{FromRequest, Request};
pub use crate::request_init::*;
pub use crate::response::{IntoResponse, Response, ResponseBody};
pub use crate::router::{RouteContext, RouteParams, Router};
pub use crate::schedule::*;
pub use crate::socket::*;
pub use crate::streams::*;
pub use crate::websocket::*;

mod abort;
mod cache;
mod cf;
mod context;
mod cors;
// Require pub module for macro export
#[cfg(feature = "d1")]
/// **Requires** `d1` feature.
pub mod d1;
mod date;
mod delay;
pub mod durable;
mod dynamic_dispatch;
mod env;
mod error;
mod fetcher;
mod formdata;
mod global;
mod headers;
mod http;
#[cfg(feature = "queue")]
mod queue;
mod r2;
mod request;
mod request_init;
mod response;
mod router;
mod schedule;
pub mod send;
mod socket;
mod streams;
mod websocket;

pub type Result<T> = StdResult<T, error::Error>;

#[cfg(feature = "http")]
/// **Requires** `http` feature. A convenience Body type which wraps [`web_sys::ReadableStream`](web_sys::ReadableStream)
/// and implements [`http_body::Body`](http_body::Body)
pub use http::body::Body;
#[cfg(feature = "http")]
pub use http::{
    request::from_wasm as request_from_wasm, request::to_wasm as request_to_wasm,
    response::from_wasm as response_from_wasm, response::to_wasm as response_to_wasm,
};
#[cfg(feature = "http")]
/// **Requires** `http` feature. Type alias for `http::Request<worker::Body>`.
pub type HttpRequest = ::http::Request<http::body::Body>;
#[cfg(feature = "http")]
/// **Requires** `http` feature. Type alias for `http::Response<worker::Body>`.
pub type HttpResponse = ::http::Response<http::body::Body>;