Skip to main content

dioxus_cloudflare/
lib.rs

1//! # dioxus-cloudflare
2//!
3//! The missing bridge between Dioxus server functions and Cloudflare Workers.
4//!
5//! This crate connects Dioxus's `#[server]` macro (via the `axum_core` feature
6//! in `dioxus-fullstack`) to the Cloudflare Workers runtime. Write one function
7//! in your shared crate — it compiles to a client fetch stub *and* a Worker
8//! handler automatically.
9//!
10//! ## Quick Start
11//!
12//! **Worker entry point:**
13//!
14//! ```rust,ignore
15//! use worker::*;
16//! use dioxus_cloudflare::prelude::*;
17//!
18//! extern "C" { fn __wasm_call_ctors(); }
19//!
20//! #[event(fetch)]
21//! async fn fetch(req: Request, env: Env, _ctx: Context) -> Result<Response> {
22//!     unsafe { __wasm_call_ctors(); }
23//!     dioxus_cloudflare::handle(req, env).await
24//! }
25//! ```
26//!
27//! **Server function (shared crate):**
28//!
29//! ```rust,ignore
30//! use dioxus::prelude::*;
31//! use dioxus_cloudflare::prelude::*;
32//!
33//! #[server]
34//! pub async fn get_user(id: String) -> Result<User, ServerFnError> {
35//!     let db = cf::d1("DB")?;
36//!     // ...
37//! }
38//! ```
39//!
40//! **Client component (calls it like a normal function):**
41//!
42//! ```rust,ignore
43//! let user = get_user("abc".into()).await;
44//! ```
45//!
46//! ## Architecture
47//!
48//! ```text
49//! Client WASM                    Cloudflare Worker
50//! ┌──────────┐    fetch()    ┌─────────────────────┐
51//! │ #[server] │ ───────────▶ │ handle(req, env)     │
52//! │ generates │              │   ↓ set_context()    │
53//! │ POST to   │              │   ↓ worker→http req  │
54//! │ /api/...  │              │   ↓ Axum dispatch    │
55//! │           │ ◀─ stream ─  │   ↓ http→worker resp │
56//! └──────────┘               └─────────────────────┘
57//! ```
58
59mod bindings;
60mod context;
61mod cookie;
62mod error;
63mod handler;
64pub mod prelude;
65#[cfg(feature = "ssr")]
66mod ssr;
67#[cfg(feature = "ssr")]
68mod streaming;
69mod websocket;
70
71/// Access Cloudflare Worker bindings and request context from inside
72/// `#[server]` functions.
73///
74/// ## Binding shortcuts
75///
76/// - [`cf::d1()`] — D1 database (combines env + binding lookup + error conversion)
77/// - [`cf::kv()`] — Workers KV namespace
78/// - [`cf::r2()`] — R2 bucket
79/// - [`cf::durable_object()`] — Durable Object namespace
80/// - [`cf::queue()`] — Queue producer (requires `queue` feature)
81///
82/// ## Raw access
83///
84/// - [`cf::env()`] — the full Worker `Env` (for bindings without a shorthand)
85/// - [`cf::req()`] — the raw `worker::Request` (headers, IP)
86///
87/// ## Incoming cookies
88///
89/// - [`cf::cookie()`] — read a named cookie from the request
90/// - [`cf::cookies()`] — read all cookies from the request
91///
92/// ## Outgoing cookies
93///
94/// - [`cf::set_cookie()`] — queue an HttpOnly auth cookie (secure defaults)
95/// - [`cf::set_cookie_with()`] — queue a cookie with custom options
96/// - [`cf::clear_cookie()`] — queue a cookie-clearing header (logout)
97///
98/// Outgoing cookies are queued in thread-local storage and applied to the
99/// response by [`handle`] — no `&mut Response` needed inside server functions.
100///
101/// ## WebSocket helpers
102///
103/// - [`cf::websocket_upgrade()`] — create a `WebSocketPair` and 101 response in one call
104/// - [`cf::websocket_pair()`] — create a raw `WebSocketPair` for custom handling
105pub mod cf {
106    pub use crate::bindings::{d1, durable_object, kv, r2};
107    #[cfg(feature = "queue")]
108    pub use crate::bindings::queue;
109    pub use crate::context::{env, req};
110    pub use crate::cookie::{
111        clear_cookie, cookie, cookies, set_cookie, set_cookie_with, CookieBuilder, SameSite,
112    };
113    pub use crate::websocket::{websocket_pair, websocket_upgrade};
114}
115
116pub use error::{CfError, CfResultExt};
117pub use handler::{handle, Handler};
118
119// Re-export ServerFnError so error.rs can reference it without users needing
120// to add dioxus as a direct dependency just for the error type.
121#[doc(hidden)]
122pub use dioxus::prelude::ServerFnError;