Compare commits

..

1 Commits

Author SHA1 Message Date
Sam Judelson
ef4c628994 add note on how to get ResponseOptions 2024-02-28 14:21:30 -05:00
15 changed files with 54 additions and 163 deletions

View File

@@ -25,23 +25,23 @@ members = [
exclude = ["benchmarks", "examples"]
[workspace.package]
version = "0.6.9"
version = "0.6.6"
rust-version = "1.75"
[workspace.dependencies]
leptos = { path = "./leptos", version = "0.6.9" }
leptos_dom = { path = "./leptos_dom", version = "0.6.9" }
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.6.9" }
leptos_macro = { path = "./leptos_macro", version = "0.6.9" }
leptos_reactive = { path = "./leptos_reactive", version = "0.6.9" }
leptos_server = { path = "./leptos_server", version = "0.6.9" }
server_fn = { path = "./server_fn", version = "0.6.9" }
server_fn_macro = { path = "./server_fn_macro", version = "0.6.9" }
leptos = { path = "./leptos", version = "0.6.5" }
leptos_dom = { path = "./leptos_dom", version = "0.6.5" }
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.6.5" }
leptos_macro = { path = "./leptos_macro", version = "0.6.5" }
leptos_reactive = { path = "./leptos_reactive", version = "0.6.5" }
leptos_server = { path = "./leptos_server", version = "0.6.5" }
server_fn = { path = "./server_fn", version = "0.6.5" }
server_fn_macro = { path = "./server_fn_macro", version = "0.6.5" }
server_fn_macro_default = { path = "./server_fn/server_fn_macro_default", version = "0.6" }
leptos_config = { path = "./leptos_config", version = "0.6.9" }
leptos_router = { path = "./router", version = "0.6.9" }
leptos_meta = { path = "./meta", version = "0.6.9" }
leptos_integration_utils = { path = "./integrations/utils", version = "0.6.9" }
leptos_config = { path = "./leptos_config", version = "0.6.5" }
leptos_router = { path = "./router", version = "0.6.5" }
leptos_meta = { path = "./meta", version = "0.6.5" }
leptos_integration_utils = { path = "./integrations/utils", version = "0.6.5" }
[profile.release]
codegen-units = 1

View File

@@ -6,17 +6,9 @@ extend = [
[tasks.integration-test]
description = "Run integration test with automated start and stop of processes"
env = { SPAWN_CLIENT_PROCESS = "1" }
run_task = { name = ["start", "wait-test-stop"], parallel = true }
dependencies = ["start", "wait-one", "test-playwright", "stop"]
[tasks.wait-test-stop]
private = true
dependencies = ["wait-server", "test-playwright", "stop"]
[tasks.wait-server]
[tasks.wait-one]
script = '''
for run in {1..12}; do
echo "Waiting to ensure server is started..."
sleep 10
done
echo "Times up, running tests"
sleep 1
'''

View File

@@ -7,8 +7,9 @@ pub struct Todos(pub Vec<Todo>);
const STORAGE_KEY: &str = "todos-leptos";
impl Default for Todos {
fn default() -> Self {
// Basic operations to manipulate the todo list: nothing really interesting here
impl Todos {
pub fn new() -> Self {
let starting_todos =
window()
.local_storage()
@@ -22,10 +23,7 @@ impl Default for Todos {
.unwrap_or_default();
Self(starting_todos)
}
}
// Basic operations to manipulate the todo list: nothing really interesting here
impl Todos {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
@@ -88,6 +86,12 @@ impl Todos {
}
}
impl Default for Todos {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct Todo {
pub id: Uuid,
@@ -132,7 +136,7 @@ const ENTER_KEY: u32 = 13;
#[component]
pub fn TodoMVC() -> impl IntoView {
// The `todos` are a signal, since we need to reactively update the list
let (todos, set_todos) = create_signal(Todos::default());
let (todos, set_todos) = create_signal(Todos::new());
// We provide a context that each <Todo/> component can use to update the list
// Here, I'm just passing the `WriteSignal`; a <Todo/> doesn't need to read the whole list

View File

@@ -79,17 +79,10 @@ impl ResponseParts {
}
/// Allows you to override details of the HTTP response like the status code and add Headers/Cookies.
///
/// `ResponseOptions` is provided via context when you use most of the handlers provided in this
/// crate, including [`.leptos_routes`](LeptosRoutes::leptos_routes),
/// [`.leptos_routes_with_context`](LeptosRoutes::leptos_routes_with_context), [`handle_server_fns`], etc.
/// You can find the full set of provided context types in each handler function.
///
/// If you provide your own handler, you will need to provide `ResponseOptions` via context
/// yourself if you want to access it via context.
/// ```rust,ignore
/// ResponseOptions is stored in your server's context if you've called `.leptos_routes` on your router.
/// ```rust
/// #[server]
/// pub async fn get_opts() -> Result<(), ServerFnError> {
/// pub async fn get_opts() -> Result<(),ServerFnError> {
/// let opts = expect_context::<leptos_axum::ResponseOptions>();
/// Ok(())
/// }

View File

@@ -104,7 +104,7 @@ pub fn html_parts_separated(
"() => mod.hydrate()"
};
let (js_hash, wasm_hash, css_hash) = get_hashes(options);
let (js_hash, wasm_hash, css_hash) = get_hashes(&options);
let head = head.replace(
&format!("{output_name}.css"),
@@ -150,7 +150,7 @@ fn get_hashes(options: &LeptosOptions) -> (String, String, String) {
("css".to_string(), "".to_string()),
]);
if options.hash_files {
if options.frontend_files_content_hashes {
let hash_path = env::current_exe()
.map(|path| {
path.parent().map(|p| p.to_path_buf()).unwrap_or_default()

View File

@@ -173,9 +173,6 @@ where
runtime,
);
#[cfg(feature = "experimental-islands")]
let prev_no_hydrate =
SharedContext::no_hydrate();
#[cfg(feature = "experimental-islands")]
{
SharedContext::set_no_hydrate(
@@ -183,7 +180,7 @@ where
);
}
let rendered = with_owner(owner, {
with_owner(owner, {
move || {
HydrationCtx::continue_from(
current_id,
@@ -197,15 +194,7 @@ where
.render_to_string()
.to_string()
}
});
#[cfg(feature = "experimental-islands")]
SharedContext::set_no_hydrate(
prev_no_hydrate,
);
#[allow(clippy::let_and_return)]
rendered
})
}
},
// in-order streaming
@@ -216,9 +205,6 @@ where
runtime,
);
#[cfg(feature = "experimental-islands")]
let prev_no_hydrate =
SharedContext::no_hydrate();
#[cfg(feature = "experimental-islands")]
{
SharedContext::set_no_hydrate(
@@ -226,7 +212,7 @@ where
);
}
let rendered = with_owner(owner, {
with_owner(owner, {
move || {
HydrationCtx::continue_from(
current_id,
@@ -239,15 +225,7 @@ where
.into_view()
.into_stream_chunks()
}
});
#[cfg(feature = "experimental-islands")]
SharedContext::set_no_hydrate(
prev_no_hydrate,
);
#[allow(clippy::let_and_return)]
rendered
})
}
},
);

View File

@@ -76,9 +76,9 @@ pub struct LeptosOptions {
pub hash_file: String,
/// If true, hashes will be generated for all files in the site_root and added to their file names.
/// Defaults to `true`.
#[builder(default = default_hash_files())]
#[serde(default = "default_hash_files")]
pub hash_files: bool,
#[builder(default = default_frontend_files_content_hashes())]
#[serde(default = "default_frontend_files_content_hashes")]
pub frontend_files_content_hashes: bool,
}
impl LeptosOptions {
@@ -118,7 +118,14 @@ impl LeptosOptions {
)?,
not_found_path: env_w_default("LEPTOS_NOT_FOUND_PATH", "/404")?,
hash_file: env_w_default("LEPTOS_HASH_FILE_NAME", "hash.txt")?,
hash_files: env_w_default("LEPTOS_HASH_FILES", "false")?.parse()?,
frontend_files_content_hashes: env_w_default(
"LEPTOS_FRONTEND_FILES_CONTENT_HASHES",
"ON",
)?
.to_uppercase()
.replace("ON", "true")
.replace("OFF", "false")
.parse()?,
})
}
}
@@ -161,8 +168,8 @@ fn default_hash_file_name() -> String {
"hash.txt".to_string()
}
fn default_hash_files() -> bool {
false
fn default_frontend_files_content_hashes() -> bool {
true
}
fn env_wo_default(key: &str) -> Result<Option<String>, LeptosConfigError> {

View File

@@ -447,7 +447,7 @@ impl ToTokens for Model {
};
quote! {
#[::leptos::wasm_bindgen::prelude::wasm_bindgen(wasm_bindgen = ::leptos::wasm_bindgen)]
#[::leptos::wasm_bindgen::prelude::wasm_bindgen]
#[allow(non_snake_case)]
pub fn #hydrate_fn_name(el: ::leptos::web_sys::HtmlElement) {
if let Some(Ok(key)) = el.dataset().get(::leptos::wasm_bindgen::intern("hkc")).map(|key| std::str::FromStr::from_str(&key)) {

View File

@@ -339,13 +339,11 @@ thread_local! {
impl SharedContext {
/// Whether the renderer should currently add hydration IDs.
pub fn no_hydrate() -> bool {
println!("no_hydrate == {}", NO_HYDRATE.with(Cell::get));
NO_HYDRATE.with(Cell::get)
}
/// Sets whether the renderer should not add hydration IDs.
pub fn set_no_hydrate(hydrate: bool) {
println!("set_no_hydrate == {}", hydrate);
NO_HYDRATE.with(|cell| cell.set(hydrate));
}

View File

@@ -165,7 +165,7 @@ pub fn create_owning_memo<T>(
f: impl Fn(Option<T>) -> (T, bool) + 'static,
) -> Memo<T>
where
T: 'static,
T: PartialEq + 'static,
{
Runtime::current().create_owning_memo(f)
}
@@ -352,7 +352,7 @@ impl<T> Memo<T> {
#[track_caller]
pub fn new_owning(f: impl Fn(Option<T>) -> (T, bool) + 'static) -> Memo<T>
where
T: 'static,
T: PartialEq + 'static,
{
create_owning_memo(f)
}

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_meta"
version = "0.6.9"
version = "0.6.6"
edition = "2021"
authors = ["Greg Johnston"]
license = "MIT"

View File

@@ -1,8 +1,8 @@
[package]
name = "leptos_router"
version = "0.6.9"
version = "0.6.6"
edition = "2021"
authors = ["Greg Johnston", "Ben Wishovich"]
authors = ["Greg Johnston"]
license = "MIT"
readme = "../README.md"
repository = "https://github.com/leptos-rs/leptos"

View File

@@ -54,7 +54,6 @@ rkyv = { version = "0.7", features = [
"uuid",
"strict",
], optional = true }
rmp-serde = { version = "1.1", optional = true }
# client
gloo-net = { version = "0.5", optional = true }
@@ -103,7 +102,6 @@ multipart = ["browser", "dep:multer"]
url = ["dep:serde_qs"]
cbor = ["dep:ciborium"]
rkyv = ["dep:rkyv"]
msgpack = ["dep:rmp-serde"]
default-tls = ["reqwest?/default-tls"]
rustls = ["reqwest?/rustls-tls"]
reqwest = ["dep:reqwest"]

View File

@@ -44,11 +44,6 @@ mod multipart;
#[cfg(feature = "multipart")]
pub use multipart::*;
#[cfg(feature = "msgpack")]
mod msgpack;
#[cfg(feature = "msgpack")]
pub use msgpack::*;
mod stream;
use crate::error::ServerFnError;
use futures::Future;

View File

@@ -1,74 +0,0 @@
use super::{Encoding, FromReq, FromRes, IntoReq, IntoRes};
use crate::{
error::ServerFnError,
request::{ClientReq, Req},
response::{ClientRes, Res},
};
use bytes::Bytes;
use http::Method;
use serde::{de::DeserializeOwned, Serialize};
/// A codec for MessagePack.
pub struct MsgPack;
impl Encoding for MsgPack {
const CONTENT_TYPE: &'static str = "application/msgpack";
const METHOD: Method = Method::POST;
}
impl<T, Request, Err> IntoReq<MsgPack, Request, Err> for T
where
Request: ClientReq<Err>,
T: Serialize,
{
fn into_req(
self,
path: &str,
accepts: &str,
) -> Result<Request, ServerFnError<Err>> {
let data = rmp_serde::to_vec(&self)
.map_err(|e| ServerFnError::Serialization(e.to_string()))?;
Request::try_new_post_bytes(
path,
MsgPack::CONTENT_TYPE,
accepts,
Bytes::from(data),
)
}
}
impl<T, Request, Err> FromReq<MsgPack, Request, Err> for T
where
Request: Req<Err> + Send,
T: DeserializeOwned,
{
async fn from_req(req: Request) -> Result<Self, ServerFnError<Err>> {
let data = req.try_into_bytes().await?;
rmp_serde::from_slice::<T>(&data)
.map_err(|e| ServerFnError::Args(e.to_string()))
}
}
impl<T, Response, Err> IntoRes<MsgPack, Response, Err> for T
where
Response: Res<Err>,
T: Serialize + Send,
{
async fn into_res(self) -> Result<Response, ServerFnError<Err>> {
let data = rmp_serde::to_vec(&self)
.map_err(|e| ServerFnError::Serialization(e.to_string()))?;
Response::try_from_bytes(MsgPack::CONTENT_TYPE, Bytes::from(data))
}
}
impl<T, Response, Err> FromRes<MsgPack, Response, Err> for T
where
Response: ClientRes<Err> + Send,
T: DeserializeOwned,
{
async fn from_res(res: Response) -> Result<Self, ServerFnError<Err>> {
let data = res.try_into_bytes().await?;
rmp_serde::from_slice(&data)
.map_err(|e| ServerFnError::Deserialization(e.to_string()))
}
}