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;
69
70/// Access Cloudflare Worker bindings and request context from inside
71/// `#[server]` functions.
72///
73/// ## Binding shortcuts
74///
75/// - [`cf::d1()`] — D1 database (combines env + binding lookup + error conversion)
76/// - [`cf::kv()`] — Workers KV namespace
77/// - [`cf::r2()`] — R2 bucket
78/// - [`cf::durable_object()`] — Durable Object namespace
79/// - [`cf::queue()`] — Queue producer (requires `queue` feature)
80///
81/// ## Raw access
82///
83/// - [`cf::env()`] — the full Worker `Env` (for bindings without a shorthand)
84/// - [`cf::req()`] — the raw `worker::Request` (headers, IP)
85///
86/// ## Incoming cookies
87///
88/// - [`cf::cookie()`] — read a named cookie from the request
89/// - [`cf::cookies()`] — read all cookies from the request
90///
91/// ## Outgoing cookies
92///
93/// - [`cf::set_cookie()`] — queue an HttpOnly auth cookie (secure defaults)
94/// - [`cf::set_cookie_with()`] — queue a cookie with custom options
95/// - [`cf::clear_cookie()`] — queue a cookie-clearing header (logout)
96///
97/// Outgoing cookies are queued in thread-local storage and applied to the
98/// response by [`handle`] — no `&mut Response` needed inside server functions.
99pub mod cf {
100 pub use crate::bindings::{d1, durable_object, kv, r2};
101 #[cfg(feature = "queue")]
102 pub use crate::bindings::queue;
103 pub use crate::context::{env, req};
104 pub use crate::cookie::{
105 clear_cookie, cookie, cookies, set_cookie, set_cookie_with, CookieBuilder, SameSite,
106 };
107}
108
109pub use error::{CfError, CfResultExt};
110pub use handler::{handle, Handler};
111
112// Re-export ServerFnError so error.rs can reference it without users needing
113// to add dioxus as a direct dependency just for the error type.
114#[doc(hidden)]
115pub use dioxus::prelude::ServerFnError;