feat(axum): support axum 0.8 applications
Upgrade the integration crate and examples to Axum 0.8 and use the native async extractor traits while preserving hemx routing, request, runtime, and effect behavior. req: axum/002
This commit is contained in:
@@ -68,4 +68,4 @@ Keep it stable. Prefer pointers to canonical sources over copied structure, file
|
|||||||
- Opaque island JavaScript is a leaf adapter for high-frequency local behavior only; client-local handlers keep the server-handler shape while `hemx-wasm` owns concrete opt-in syntax. Use native events/generated helpers at the boundary and do not introduce a component runtime, client state graph, VDOM, selector interop, or second UI model. req: canonical_authoring/017 req: client_local/001 req: client_local/003 req: client_local/004 req: interop/001 req: interop/002 req: interop/003 req: interop/006 req: interop/007 req: interop/008 req: interop/009 req: interop/010 req: interop/011 req: interop/012
|
- Opaque island JavaScript is a leaf adapter for high-frequency local behavior only; client-local handlers keep the server-handler shape while `hemx-wasm` owns concrete opt-in syntax. Use native events/generated helpers at the boundary and do not introduce a component runtime, client state graph, VDOM, selector interop, or second UI model. req: canonical_authoring/017 req: client_local/001 req: client_local/003 req: client_local/004 req: interop/001 req: interop/002 req: interop/003 req: interop/006 req: interop/007 req: interop/008 req: interop/009 req: interop/010 req: interop/011 req: interop/012
|
||||||
- Host capability adapters must stay at the `hemx-host` boundary: typed capabilities use fire/request/stream/schedule shapes; adapters may call host APIs and return host events, but they must not mutate DOM or own app/domain state. req: host/001 req: host/002
|
- Host capability adapters must stay at the `hemx-host` boundary: typed capabilities use fire/request/stream/schedule shapes; adapters may call host APIs and return host events, but they must not mutate DOM or own app/domain state. req: host/001 req: host/002
|
||||||
- Local/offline app behavior should be commands/events/projections; do not add `hemx-local`, stored DOM patches, stored `EffectBatch` truth, or a core client state graph without a proven reusable contract. Atoms are explicit addressable/bootstrap/sync resources, not the default state container or a reactive framework. Replay, reconciliation, export, and deletion rules stay explicit product decisions, and exemplars should show UI effects as app-state output. The local-first multiplayer kanban remains an advanced north-star integration milestone, not beginner/API surface scope. req: canonical_authoring/018 req: canonical_authoring/019 req: state/001 req: state/002 req: state/003 req: state/004 req: state/005 req: state/006 req: state/007 req: local/001 req: local/002 req: local/003 req: local/004 req: milestone/001 req: milestone/002 req: milestone/003
|
- Local/offline app behavior should be commands/events/projections; do not add `hemx-local`, stored DOM patches, stored `EffectBatch` truth, or a core client state graph without a proven reusable contract. Atoms are explicit addressable/bootstrap/sync resources, not the default state container or a reactive framework. Replay, reconciliation, export, and deletion rules stay explicit product decisions, and exemplars should show UI effects as app-state output. The local-first multiplayer kanban remains an advanced north-star integration milestone, not beginner/API surface scope. req: canonical_authoring/018 req: canonical_authoring/019 req: state/001 req: state/002 req: state/003 req: state/004 req: state/005 req: state/006 req: state/007 req: local/001 req: local/002 req: local/003 req: local/004 req: milestone/001 req: milestone/002 req: milestone/003
|
||||||
- Axum apps should serve and load the shared runtime through hemx-axum helpers such as `runtime_js_path()` and `runtime_js()`, not hard-coded `/hemx.js` URLs or app-owned cache-busting strings; keep hemx-axum as route/runtime/handler adapter around generated partial swaps, not a routing owner. req: axum_integration/001 req: axum_integration/002 req: axum_integration/003 req: axum_integration/005 req: axum_integration/006
|
- Axum 0.8 apps should serve and load the shared runtime through hemx-axum helpers such as `runtime_js_path()` and `runtime_js()`, not hard-coded `/hemx.js` URLs or app-owned cache-busting strings; keep hemx-axum as route/runtime/handler adapter around generated partial swaps, not a routing owner. req: axum/002 req: axum_integration/001 req: axum_integration/002 req: axum_integration/003 req: axum_integration/005 req: axum_integration/006
|
||||||
|
|||||||
Generated
+9
-12
@@ -39,13 +39,13 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum"
|
name = "axum"
|
||||||
version = "0.7.9"
|
version = "0.8.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"
|
checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
|
||||||
"axum-core",
|
"axum-core",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"form_urlencoded",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
@@ -59,8 +59,7 @@ dependencies = [
|
|||||||
"multer",
|
"multer",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustversion",
|
"serde_core",
|
||||||
"serde",
|
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_path_to_error",
|
"serde_path_to_error",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
@@ -74,19 +73,17 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum-core"
|
name = "axum-core"
|
||||||
version = "0.4.5"
|
version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
|
checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-core",
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"mime",
|
"mime",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustversion",
|
|
||||||
"sync_wrapper",
|
"sync_wrapper",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
@@ -994,9 +991,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchit"
|
name = "matchit"
|
||||||
version = "0.7.3"
|
version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
|
|||||||
+4
-1
@@ -511,6 +511,9 @@ what a valid business email is. [north_star]
|
|||||||
### req: wire/005
|
### req: wire/005
|
||||||
0 005 No JSON anywhere in hemx-internal artifacts. Public request/response envelopes use `application/x-www-form-urlencoded`; effects and symbols use postcard. `application/json` is acceptable only at integration boundaries. [north_star]
|
0 005 No JSON anywhere in hemx-internal artifacts. Public request/response envelopes use `application/x-www-form-urlencoded`; effects and symbols use postcard. `application/json` is acceptable only at integration boundaries. [north_star]
|
||||||
|
|
||||||
|
### req: wire/007
|
||||||
|
0 007 `EffectBatch::encoded_len` reports the exact canonical wire size, and `to_wire` uses it to pre-size encoding to one output allocation while preserving canonical bytes. [north_star]
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## abi
|
## abi
|
||||||
@@ -585,7 +588,7 @@ what a valid business email is. [north_star]
|
|||||||
0 006 Page helpers add shell/title/history/fallback behavior without changing the render/target/effect model. [north_star]
|
0 006 Page helpers add shell/title/history/fallback behavior without changing the render/target/effect model. [north_star]
|
||||||
|
|
||||||
### req: axum/002
|
### req: axum/002
|
||||||
0 002 Existing Axum routes remain normal Axum routes. hemx does not own routing. hemx-axum only mounts handler dispatch, runtime assets, and optional push endpoints. [north_star]
|
0 002 Existing Axum 0.8 routes remain normal Axum routes. hemx does not own routing. hemx-axum only mounts handler dispatch, runtime assets, and optional push endpoints. [north_star]
|
||||||
|
|
||||||
### req: axum/003
|
### req: axum/003
|
||||||
0 003 Interactive fragments from `/demo/...` HTMX endpoints are Rust handlers returning generated target commands. Registration reads as generated handle/page/partial helpers, not low-level registry wiring. [north_star]
|
0 003 Interactive fragments from `/demo/...` HTMX endpoints are Rust handlers returning generated target commands. Registration reads as generated handle/page/partial helpers, not low-level registry wiring. [north_star]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ publish = false
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.7"
|
axum = "0.8"
|
||||||
hemplate = { path = "../../../hemplate/hemplate" }
|
hemplate = { path = "../../../hemplate/hemplate" }
|
||||||
hemx = { path = "../../hemx" }
|
hemx = { path = "../../hemx" }
|
||||||
hemx-axum = { path = "../../hemx-axum" }
|
hemx-axum = { path = "../../hemx-axum" }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ publish = false
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.7"
|
axum = "0.8"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
hemplate = { path = "../../../hemplate/hemplate" }
|
hemplate = { path = "../../../hemplate/hemplate" }
|
||||||
hemx = { path = "../../hemx" }
|
hemx = { path = "../../hemx" }
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ name = "hemx-saas-example"
|
|||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.7"
|
axum = "0.8"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
hemplate = { path = "../../../hemplate/hemplate" }
|
hemplate = { path = "../../../hemplate/hemplate" }
|
||||||
hemx = { path = "../../hemx" }
|
hemx = { path = "../../hemx" }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ publish = false
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.7"
|
axum = "0.8"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
hemplate = { path = "../../../hemplate/hemplate" }
|
hemplate = { path = "../../../hemplate/hemplate" }
|
||||||
hemx = { path = "../../hemx" }
|
hemx = { path = "../../hemx" }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ publish = false
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.7"
|
axum = "0.8"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
hemplate = { path = "../../../hemplate/hemplate" }
|
hemplate = { path = "../../../hemplate/hemplate" }
|
||||||
hemx = { path = "../../hemx" }
|
hemx = { path = "../../hemx" }
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ name = "hemx-workout-example"
|
|||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.7"
|
axum = "0.8"
|
||||||
hemplate = { path = "../../../hemplate/hemplate" }
|
hemplate = { path = "../../../hemplate/hemplate" }
|
||||||
hemx = { path = "../../hemx" }
|
hemx = { path = "../../hemx" }
|
||||||
hemx-axum = { path = "../../hemx-axum" }
|
hemx-axum = { path = "../../hemx-axum" }
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ edition.workspace = true
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = { version = "0.7", default-features = false, features = ["multipart", "tokio"] }
|
axum = { version = "0.8", default-features = false, features = ["multipart", "tokio"] }
|
||||||
futures-util = { version = "0.3", default-features = false }
|
futures-util = { version = "0.3", default-features = false }
|
||||||
hemx-core = { path = "../hemx-core" }
|
hemx-core = { path = "../hemx-core" }
|
||||||
hemx-js = { path = "../hemx-js" }
|
hemx-js = { path = "../hemx-js" }
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use axum::async_trait;
|
|
||||||
use axum::body::{to_bytes, Body};
|
use axum::body::{to_bytes, Body};
|
||||||
pub use axum::extract::State;
|
pub use axum::extract::State;
|
||||||
use axum::extract::{FromRequest, FromRequestParts, Multipart};
|
use axum::extract::{FromRequest, FromRequestParts, Multipart};
|
||||||
@@ -91,7 +90,6 @@ impl PageRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<S> FromRequestParts<S> for PageRequest
|
impl<S> FromRequestParts<S> for PageRequest
|
||||||
where
|
where
|
||||||
S: Send + Sync,
|
S: Send + Sync,
|
||||||
@@ -1237,7 +1235,6 @@ impl IntoResponse for InteractionFormRejection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<S> FromRequest<S> for InteractionRequest
|
impl<S> FromRequest<S> for InteractionRequest
|
||||||
where
|
where
|
||||||
S: Send + Sync,
|
S: Send + Sync,
|
||||||
@@ -1251,7 +1248,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<S> FromRequest<S> for InteractionForm
|
impl<S> FromRequest<S> for InteractionForm
|
||||||
where
|
where
|
||||||
S: Send + Sync,
|
S: Send + Sync,
|
||||||
|
|||||||
Reference in New Issue
Block a user