Merge pull request #1791 from ealmloff/breaking
Remove scope, use_state, use_ref, bump allocator and make everything 'static
This commit is contained in:
517 files changed
+17126
-20669
No files matched your search
@@ -1,5 +1,15 @@
|
||||
use crate::{LiveViewError, LiveViewSocket};
|
||||
use axum::extract::ws::{Message, WebSocket};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{interpreter_glue, LiveViewError, LiveViewSocket, LiveviewRouter};
|
||||
use axum::{
|
||||
extract::{
|
||||
ws::{Message, WebSocket},
|
||||
WebSocketUpgrade,
|
||||
},
|
||||
response::Html,
|
||||
routing::*,
|
||||
Router,
|
||||
};
|
||||
use futures_util::{SinkExt, StreamExt};
|
||||
|
||||
/// Convert an Axum WebSocket into a `LiveViewSocket`.
|
||||
@@ -22,3 +32,60 @@ fn transform_rx(message: Result<Message, axum::Error>) -> Result<Vec<u8>, LiveVi
|
||||
async fn transform_tx(message: Vec<u8>) -> Result<Message, axum::Error> {
|
||||
Ok(Message::Binary(message))
|
||||
}
|
||||
|
||||
impl LiveviewRouter for Router {
|
||||
fn create_default_liveview_router() -> Self {
|
||||
Router::new()
|
||||
}
|
||||
|
||||
fn with_virtual_dom(
|
||||
self,
|
||||
route: &str,
|
||||
app: impl Fn() -> dioxus_core::prelude::VirtualDom + Send + Sync + 'static,
|
||||
) -> Self {
|
||||
let view = crate::LiveViewPool::new();
|
||||
|
||||
let ws_path = format!("{}/ws", route);
|
||||
let title = crate::app_title();
|
||||
|
||||
let index_page_with_glue = move |glue: &str| {
|
||||
Html(format!(
|
||||
r#"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head> <title>{title}</title> </head>
|
||||
<body> <div id="main"></div> </body>
|
||||
{glue}
|
||||
</html>
|
||||
"#,
|
||||
))
|
||||
};
|
||||
|
||||
let app = Arc::new(app);
|
||||
|
||||
self.route(
|
||||
&ws_path,
|
||||
get(move |ws: WebSocketUpgrade| async move {
|
||||
let app = app.clone();
|
||||
ws.on_upgrade(move |socket| async move {
|
||||
_ = view
|
||||
.launch_virtualdom(axum_socket(socket), move || app())
|
||||
.await;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.route(
|
||||
route,
|
||||
get(move || async move { index_page_with_glue(&interpreter_glue(&ws_path)) }),
|
||||
)
|
||||
}
|
||||
|
||||
async fn start(self, address: impl Into<std::net::SocketAddr>) {
|
||||
if let Err(err) = axum::Server::bind(&address.into())
|
||||
.serve(self.into_make_service())
|
||||
.await
|
||||
{
|
||||
eprintln!("Failed to start axum server: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
use std::future::Future;
|
||||
|
||||
use dioxus_core::{Element, VirtualDom};
|
||||
|
||||
#[cfg(feature = "warp")]
|
||||
pub mod warp_adapter;
|
||||
#[cfg(feature = "warp")]
|
||||
pub use warp_adapter::*;
|
||||
|
||||
#[cfg(feature = "axum")]
|
||||
pub mod axum_adapter;
|
||||
#[cfg(feature = "axum")]
|
||||
pub use axum_adapter::*;
|
||||
|
||||
#[cfg(feature = "salvo")]
|
||||
pub mod salvo_adapter;
|
||||
#[cfg(feature = "salvo")]
|
||||
pub use salvo_adapter::*;
|
||||
|
||||
#[cfg(feature = "rocket")]
|
||||
pub mod rocket_adapter;
|
||||
#[cfg(feature = "rocket")]
|
||||
pub use rocket_adapter::*;
|
||||
|
||||
/// A trait for servers that can be used to host a LiveView app.
|
||||
pub trait LiveviewRouter {
|
||||
/// Create a new router.
|
||||
fn create_default_liveview_router() -> Self;
|
||||
|
||||
/// Add a liveview route to the server from a component
|
||||
fn with_app(self, route: &str, app: fn() -> Element) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.with_virtual_dom(route, move || VirtualDom::new(app))
|
||||
}
|
||||
|
||||
/// Add a liveview route to the server from a virtual dom.
|
||||
fn with_virtual_dom(
|
||||
self,
|
||||
route: &str,
|
||||
app: impl Fn() -> VirtualDom + Send + Sync + 'static,
|
||||
) -> Self;
|
||||
|
||||
/// Start the server on an address.
|
||||
fn start(self, address: impl Into<std::net::SocketAddr>) -> impl Future<Output = ()>;
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
use crate::LiveViewPool;
|
||||
use crate::LiveviewRouter;
|
||||
use crate::{LiveViewError, LiveViewSocket};
|
||||
use rocket::futures::{SinkExt, StreamExt};
|
||||
use rocket::response::content::RawHtml;
|
||||
use rocket::{get, routes, State};
|
||||
use rocket_ws::Channel;
|
||||
use rocket_ws::WebSocket;
|
||||
use rocket_ws::{result::Error, stream::DuplexStream, Message};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Convert a Rocket WebSocket into a `LiveViewSocket`.
|
||||
///
|
||||
@@ -21,5 +28,86 @@ fn transform_rx(message: Result<Message, Error>) -> Result<Vec<u8>, LiveViewErro
|
||||
}
|
||||
|
||||
async fn transform_tx(message: Vec<u8>) -> Result<Message, Error> {
|
||||
Ok(Message::Text(String::from_utf8_lossy(&message).to_string()))
|
||||
Ok(Message::Binary(message))
|
||||
}
|
||||
|
||||
impl LiveviewRouter for rocket::Rocket<rocket::Build> {
|
||||
fn create_default_liveview_router() -> Self {
|
||||
Self::build()
|
||||
}
|
||||
|
||||
fn with_virtual_dom(
|
||||
self,
|
||||
route: &str,
|
||||
app: impl Fn() -> dioxus_core::prelude::VirtualDom + Send + Sync + 'static,
|
||||
) -> Self {
|
||||
#[get("/")]
|
||||
async fn index(request: &rocket::route::Route) -> RawHtml<String> {
|
||||
let route = request.uri.base();
|
||||
|
||||
let glue = crate::interpreter_glue(&format!("{route}/ws",));
|
||||
|
||||
let title = crate::app_title();
|
||||
|
||||
RawHtml(format!(
|
||||
r#"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head> <title>{title}</title> </head>
|
||||
<body> <div id="main"></div> </body>
|
||||
{glue}
|
||||
</html>
|
||||
"#
|
||||
))
|
||||
}
|
||||
|
||||
#[get("/ws")]
|
||||
fn ws(ws: WebSocket, app: &State<LiveviewApp>) -> Channel<'static> {
|
||||
let app = app.inner();
|
||||
let pool = app.pool.clone();
|
||||
let app = app.app.clone();
|
||||
|
||||
ws.channel(move |stream| {
|
||||
Box::pin(async move {
|
||||
let _ = pool
|
||||
.launch_virtualdom(crate::rocket_socket(stream), move || app())
|
||||
.await;
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
struct LiveviewApp {
|
||||
app: Arc<dyn Fn() -> dioxus_core::prelude::VirtualDom + Send + Sync + 'static>,
|
||||
pool: LiveViewPool,
|
||||
}
|
||||
|
||||
let app = Arc::new(app);
|
||||
|
||||
let view = crate::LiveViewPool::new();
|
||||
|
||||
self.manage(LiveviewApp {
|
||||
app: app,
|
||||
pool: view,
|
||||
})
|
||||
.mount(route, routes![index, ws])
|
||||
}
|
||||
|
||||
async fn start(self, address: impl Into<std::net::SocketAddr>) {
|
||||
let address = address.into();
|
||||
|
||||
let figment = self
|
||||
.figment()
|
||||
.clone()
|
||||
.merge((rocket::Config::PORT, address.port()))
|
||||
.merge((rocket::Config::ADDRESS, address.ip()));
|
||||
|
||||
self.configure(figment)
|
||||
.ignite()
|
||||
.await
|
||||
.expect("Failed to ignite rocket")
|
||||
.launch()
|
||||
.await
|
||||
.expect("Failed to launch rocket");
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,16 @@
|
||||
use futures_util::{SinkExt, StreamExt};
|
||||
use salvo::ws::{Message, WebSocket};
|
||||
|
||||
use crate::LiveViewPool;
|
||||
use crate::LiveviewRouter;
|
||||
use crate::{LiveViewError, LiveViewSocket};
|
||||
use futures_util::{SinkExt, StreamExt};
|
||||
use salvo::conn::TcpListener;
|
||||
use salvo::http::StatusError;
|
||||
use salvo::websocket::WebSocketUpgrade;
|
||||
use salvo::websocket::{Message, WebSocket};
|
||||
use salvo::writing::Text;
|
||||
use salvo::Listener;
|
||||
use salvo::Server;
|
||||
use salvo::{handler, Depot, Request, Response, Router};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Convert a Salvo WebSocket into a `LiveViewSocket`.
|
||||
///
|
||||
@@ -19,5 +28,81 @@ fn transform_rx(message: Result<Message, salvo::Error>) -> Result<Vec<u8>, LiveV
|
||||
}
|
||||
|
||||
async fn transform_tx(message: Vec<u8>) -> Result<Message, salvo::Error> {
|
||||
Ok(Message::text(String::from_utf8_lossy(&message).to_string()))
|
||||
Ok(Message::binary(message))
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct LiveviewApp {
|
||||
app: Arc<dyn Fn() -> dioxus_core::prelude::VirtualDom + Send + Sync + 'static>,
|
||||
pool: Arc<LiveViewPool>,
|
||||
}
|
||||
|
||||
impl LiveviewRouter for Router {
|
||||
fn create_default_liveview_router() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
|
||||
fn with_virtual_dom(
|
||||
self,
|
||||
route: &str,
|
||||
app: impl Fn() -> dioxus_core::prelude::VirtualDom + Send + Sync + 'static,
|
||||
) -> Self {
|
||||
let app = Arc::new(app);
|
||||
|
||||
let view = crate::LiveViewPool::new();
|
||||
|
||||
self.push(
|
||||
Router::with_path(route)
|
||||
.hoop(salvo::affix::inject(LiveviewApp {
|
||||
app: app,
|
||||
pool: Arc::new(view),
|
||||
}))
|
||||
.get(index)
|
||||
.push(Router::with_path("ws").get(connect)),
|
||||
)
|
||||
}
|
||||
|
||||
async fn start(self, address: impl Into<std::net::SocketAddr>) {
|
||||
let address = address.into();
|
||||
|
||||
let acceptor = TcpListener::new(address).bind().await;
|
||||
Server::new(acceptor).serve(self).await;
|
||||
}
|
||||
}
|
||||
|
||||
#[handler]
|
||||
fn index(req: &mut Request, res: &mut Response) {
|
||||
let base = req.uri().path();
|
||||
let title = crate::app_title();
|
||||
|
||||
res.render(Text::Html(format!(
|
||||
r#"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head> <title>{title}</title> </head>
|
||||
<body> <div id="main"></div> </body>
|
||||
{glue}
|
||||
</html>
|
||||
"#,
|
||||
glue = crate::interpreter_glue(&format!("{base}/ws"))
|
||||
)));
|
||||
}
|
||||
|
||||
#[handler]
|
||||
async fn connect(
|
||||
req: &mut Request,
|
||||
depot: &mut Depot,
|
||||
res: &mut Response,
|
||||
) -> Result<(), StatusError> {
|
||||
let app = depot.obtain::<LiveviewApp>().unwrap().clone();
|
||||
let view = app.pool.clone();
|
||||
let app = app.app.clone();
|
||||
|
||||
WebSocketUpgrade::new()
|
||||
.upgrade(req, res, |ws| async move {
|
||||
_ = view
|
||||
.launch_virtualdom(crate::salvo_socket(ws), move || app())
|
||||
.await;
|
||||
})
|
||||
.await
|
||||
}
|
||||
@@ -21,5 +21,5 @@ fn transform_rx(message: Result<Message, warp::Error>) -> Result<Vec<u8>, LiveVi
|
||||
}
|
||||
|
||||
async fn transform_tx(message: Vec<u8>) -> Result<Message, warp::Error> {
|
||||
Ok(Message::text(String::from_utf8_lossy(&message).to_string()))
|
||||
Ok(Message::binary(message))
|
||||
}
|
||||
Reference in new issue
Block a user