mirror of
https://github.com/leptos-rs/leptos.git
synced 2025-12-28 11:21:55 -05:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7dfb33153 |
28
.github/workflows/autofix.yml
vendored
28
.github/workflows/autofix.yml
vendored
@@ -21,19 +21,33 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with: {toolchain: "nightly-2025-04-16", components: "rustfmt, clippy", target: "wasm32-unknown-unknown", rustflags: ""}
|
||||
with: {toolchain: nightly, components: "rustfmt, clippy", target: "wasm32-unknown-unknown", rustflags: ""}
|
||||
- name: Install Glib
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libglib2.0-dev
|
||||
- name: Install cargo-all-features
|
||||
run: cargo install --git https://github.com/sabify/cargo-all-features --branch arbitrary-command-support
|
||||
- name: Install jq
|
||||
run: sudo apt-get install jq
|
||||
- name: Format the workspace
|
||||
run: cargo fmt --all
|
||||
- name: Clippy the workspace
|
||||
run: cargo all-features clippy --allow-dirty --fix --lib --no-deps
|
||||
- run: |
|
||||
echo "Formatting the workspace"
|
||||
cargo fmt --all
|
||||
|
||||
echo "Running Clippy against each member's features (default features included)"
|
||||
for member in $(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | .name'); do
|
||||
echo "Working on member $member":
|
||||
echo -e "\tdefault-features/no-features:"
|
||||
# this will also run on members with no features or default features
|
||||
cargo clippy --allow-dirty --fix --lib --package "$member"
|
||||
|
||||
features=$(cargo metadata --no-deps --format-version 1 | jq -r ".packages[] | select(.name == \"$member\") | .features | keys[]")
|
||||
for feature in $features; do
|
||||
if [ "$feature" = "default" ]; then
|
||||
continue
|
||||
fi
|
||||
echo -e "\tfeature $feature"
|
||||
cargo clippy --allow-dirty --fix --lib --package "$member" --features "$feature"
|
||||
done
|
||||
done
|
||||
- uses: autofix-ci/action@v1.3.1
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
|
||||
8
.github/workflows/run-cargo-make-task.yml
vendored
8
.github/workflows/run-cargo-make-task.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain: [stable, nightly-2025-04-16]
|
||||
toolchain: [stable, nightly-2025-03-05]
|
||||
erased_mode: [true, false]
|
||||
steps:
|
||||
- name: Free Disk Space
|
||||
@@ -160,12 +160,6 @@ jobs:
|
||||
run: |
|
||||
cd '${{ inputs.directory }}'
|
||||
cargo make --no-workspace --profile=github-actions ci
|
||||
# Check if the counter_isomorphic can be built with leptos_debuginfo cfg flag in release mode
|
||||
- name: ${{ inputs.cargo_make_task }} with --cfg=leptos_debuginfo
|
||||
if: contains(inputs.directory, 'counter_isomorphic')
|
||||
run: |
|
||||
cd '${{ inputs.directory }}'
|
||||
RUSTFLAGS="$RUSTFLAGS --cfg leptos_debuginfo" cargo leptos build --release
|
||||
- name: Clean up ${{ inputs.directory }}
|
||||
if: always()
|
||||
run: |
|
||||
|
||||
45
Cargo.lock
generated
45
Cargo.lock
generated
@@ -263,7 +263,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "any_spawner"
|
||||
version = "0.3.0"
|
||||
version = "0.3.0-rc3"
|
||||
dependencies = [
|
||||
"async-executor",
|
||||
"futures",
|
||||
@@ -1781,7 +1781,7 @@ checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
|
||||
|
||||
[[package]]
|
||||
name = "leptos"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"any_spawner",
|
||||
"base64",
|
||||
@@ -1833,7 +1833,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leptos_actix"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"actix-files",
|
||||
"actix-http",
|
||||
@@ -1859,7 +1859,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leptos_axum"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"any_spawner",
|
||||
"axum",
|
||||
@@ -1883,7 +1883,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leptos_config"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"config",
|
||||
"regex",
|
||||
@@ -1897,7 +1897,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leptos_dom"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"leptos",
|
||||
@@ -1914,7 +1914,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leptos_hot_reload"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
@@ -1930,7 +1930,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leptos_integration_utils"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"hydration_context",
|
||||
@@ -1943,7 +1943,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leptos_macro"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"attribute-derive",
|
||||
"cfg-if",
|
||||
@@ -1963,7 +1963,7 @@ dependencies = [
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"server_fn",
|
||||
"server_fn_macro 0.8.1",
|
||||
"server_fn_macro 0.8.0-rc3",
|
||||
"syn 2.0.100",
|
||||
"tracing",
|
||||
"trybuild",
|
||||
@@ -1973,7 +1973,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leptos_meta"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"indexmap",
|
||||
@@ -1988,7 +1988,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leptos_router"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"any_spawner",
|
||||
"either_of",
|
||||
@@ -2013,7 +2013,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leptos_router_macro"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"leptos_macro",
|
||||
"leptos_router",
|
||||
@@ -2025,7 +2025,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "leptos_server"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"any_spawner",
|
||||
"base64",
|
||||
@@ -2759,7 +2759,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reactive_graph"
|
||||
version = "0.2.1"
|
||||
version = "0.2.0-rc3"
|
||||
dependencies = [
|
||||
"any_spawner",
|
||||
"async-lock",
|
||||
@@ -2782,7 +2782,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reactive_stores"
|
||||
version = "0.2.1"
|
||||
version = "0.2.0-rc3"
|
||||
dependencies = [
|
||||
"any_spawner",
|
||||
"dashmap",
|
||||
@@ -2801,7 +2801,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reactive_stores_macro"
|
||||
version = "0.2.1"
|
||||
version = "0.2.0-rc3"
|
||||
dependencies = [
|
||||
"convert_case 0.8.0",
|
||||
"proc-macro-error2",
|
||||
@@ -3298,7 +3298,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "server_fn"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"actix-ws",
|
||||
@@ -3323,7 +3323,6 @@ dependencies = [
|
||||
"reqwest",
|
||||
"rkyv",
|
||||
"rmp-serde",
|
||||
"rustc_version",
|
||||
"rustversion",
|
||||
"send_wrapper",
|
||||
"serde",
|
||||
@@ -3362,7 +3361,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "server_fn_macro"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"const_format",
|
||||
"convert_case 0.8.0",
|
||||
@@ -3375,9 +3374,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "server_fn_macro_default"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
dependencies = [
|
||||
"server_fn_macro 0.8.1",
|
||||
"server_fn_macro 0.8.0-rc3",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
@@ -3571,7 +3570,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tachys"
|
||||
version = "0.2.1"
|
||||
version = "0.2.0-rc3"
|
||||
dependencies = [
|
||||
"any_spawner",
|
||||
"async-trait",
|
||||
|
||||
38
Cargo.toml
38
Cargo.toml
@@ -40,40 +40,40 @@ members = [
|
||||
exclude = ["benchmarks", "examples", "projects"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
edition = "2021"
|
||||
rust-version = "1.76"
|
||||
|
||||
[workspace.dependencies]
|
||||
convert_case = "0.8"
|
||||
throw_error = { path = "./any_error/", version = "0.3.0" }
|
||||
any_spawner = { path = "./any_spawner/", version = "0.3.0" }
|
||||
any_spawner = { path = "./any_spawner/", version = "0.3.0-rc3" }
|
||||
const_str_slice_concat = { path = "./const_str_slice_concat", version = "0.1" }
|
||||
either_of = { path = "./either_of/", version = "0.1.5" }
|
||||
hydration_context = { path = "./hydration_context", version = "0.3.0" }
|
||||
itertools = "0.14.0"
|
||||
leptos = { path = "./leptos", version = "0.8.1" }
|
||||
leptos_config = { path = "./leptos_config", version = "0.8.1" }
|
||||
leptos_dom = { path = "./leptos_dom", version = "0.8.1" }
|
||||
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.8.1" }
|
||||
leptos_integration_utils = { path = "./integrations/utils", version = "0.8.1" }
|
||||
leptos_macro = { path = "./leptos_macro", version = "0.8.1" }
|
||||
leptos_router = { path = "./router", version = "0.8.1" }
|
||||
leptos_router_macro = { path = "./router_macro", version = "0.8.1" }
|
||||
leptos_server = { path = "./leptos_server", version = "0.8.1" }
|
||||
leptos_meta = { path = "./meta", version = "0.8.1" }
|
||||
leptos = { path = "./leptos", version = "0.8.0-rc3" }
|
||||
leptos_config = { path = "./leptos_config", version = "0.8.0-rc3" }
|
||||
leptos_dom = { path = "./leptos_dom", version = "0.8.0-rc3" }
|
||||
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.8.0-rc3" }
|
||||
leptos_integration_utils = { path = "./integrations/utils", version = "0.8.0-rc3" }
|
||||
leptos_macro = { path = "./leptos_macro", version = "0.8.0-rc3" }
|
||||
leptos_router = { path = "./router", version = "0.8.0-rc3" }
|
||||
leptos_router_macro = { path = "./router_macro", version = "0.8.0-rc3" }
|
||||
leptos_server = { path = "./leptos_server", version = "0.8.0-rc3" }
|
||||
leptos_meta = { path = "./meta", version = "0.8.0-rc3" }
|
||||
next_tuple = { path = "./next_tuple", version = "0.1.0" }
|
||||
oco_ref = { path = "./oco", version = "0.2.0" }
|
||||
or_poisoned = { path = "./or_poisoned", version = "0.1.0" }
|
||||
reactive_graph = { path = "./reactive_graph", version = "0.2.0" }
|
||||
reactive_stores = { path = "./reactive_stores", version = "0.2.0" }
|
||||
reactive_stores_macro = { path = "./reactive_stores_macro", version = "0.2.0" }
|
||||
reactive_graph = { path = "./reactive_graph", version = "0.2.0-rc3" }
|
||||
reactive_stores = { path = "./reactive_stores", version = "0.2.0-rc3" }
|
||||
reactive_stores_macro = { path = "./reactive_stores_macro", version = "0.2.0-rc3" }
|
||||
rustversion = "1"
|
||||
serde_json = "1.0.0"
|
||||
server_fn = { path = "./server_fn", version = "0.8.1" }
|
||||
server_fn_macro = { path = "./server_fn_macro", version = "0.8.1" }
|
||||
server_fn_macro_default = { path = "./server_fn/server_fn_macro_default", version = "0.8.1" }
|
||||
tachys = { path = "./tachys", version = "0.2.0" }
|
||||
server_fn = { path = "./server_fn", version = "0.8.0-rc3" }
|
||||
server_fn_macro = { path = "./server_fn_macro", version = "0.8.0-rc3" }
|
||||
server_fn_macro_default = { path = "./server_fn/server_fn_macro_default", version = "0.8.0-rc3" }
|
||||
tachys = { path = "./tachys", version = "0.2.0-rc3" }
|
||||
trybuild = "1"
|
||||
typed-builder = "0.21.0"
|
||||
thiserror = "2.0.12"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "any_spawner"
|
||||
version = "0.3.0"
|
||||
version = "0.3.0-rc3"
|
||||
authors = ["Greg Johnston"]
|
||||
license = "MIT"
|
||||
readme = "../README.md"
|
||||
|
||||
@@ -26,17 +26,12 @@ pub async fn file_and_error_handler(
|
||||
.map(|h| h.to_str().unwrap_or("none"))
|
||||
.unwrap_or("none")
|
||||
.to_string();
|
||||
let static_result = get_static_file(uri.clone(), accept_encoding).await;
|
||||
let res = get_static_file(uri.clone(), accept_encoding).await.unwrap();
|
||||
|
||||
match static_result {
|
||||
Ok(res) => {
|
||||
if res.status() == StatusCode::OK {
|
||||
res.into_response()
|
||||
} else {
|
||||
(StatusCode::NOT_FOUND, "Not found.").into_response()
|
||||
}
|
||||
}
|
||||
Err(e) => e.into_response(),
|
||||
if res.status() == StatusCode::OK {
|
||||
res.into_response()
|
||||
} else {
|
||||
(StatusCode::NOT_FOUND, "Not found.").into_response()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ pub fn Stories() -> impl IntoView {
|
||||
let stories = Resource::new(
|
||||
move || (page(), story_type()),
|
||||
move |(page, story_type)| async move {
|
||||
fetch_stories(story_type, page).await.ok()
|
||||
fetch_stories(category(&story_type), page).await.ok()
|
||||
},
|
||||
);
|
||||
let (pending, set_pending) = signal(false);
|
||||
|
||||
@@ -10,11 +10,7 @@ crate-type = ["cdylib", "rlib"]
|
||||
console_error_panic_hook = "0.1.7"
|
||||
futures = "0.3.30"
|
||||
http = "1.1"
|
||||
leptos = { path = "../../leptos", features = [
|
||||
"tracing",
|
||||
"islands",
|
||||
"islands-router",
|
||||
] }
|
||||
leptos = { path = "../../leptos", features = ["tracing", "islands"] }
|
||||
leptos_router = { path = "../../router" }
|
||||
server_fn = { path = "../../server_fn", features = ["serde-lite"] }
|
||||
leptos_axum = { path = "../../integrations/axum", features = [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Stores Example
|
||||
# Leptos Counter Example
|
||||
|
||||
This example shows how to use reactive stores, by building a client-side rendered TODO application.
|
||||
This example creates a simple counter in a client side rendered app with Rust and WASM!
|
||||
|
||||
## Getting Started
|
||||
|
||||
|
||||
10
examples/websocket/e2e/tests/fixtures/action.rs
vendored
10
examples/websocket/e2e/tests/fixtures/action.rs
vendored
@@ -10,9 +10,19 @@ pub async fn goto_path(client: &Client, path: &str) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn add_text(client: &Client, text: &str) -> Result<String> {
|
||||
fill_input(client, text).await?;
|
||||
get_label(client).await
|
||||
}
|
||||
|
||||
pub async fn fill_input(client: &Client, text: &str) -> Result<()> {
|
||||
let textbox = find::input(client).await;
|
||||
textbox.send_keys(text).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_label(client: &Client) -> Result<String> {
|
||||
let label = find::label(client).await;
|
||||
Ok(label.text().await?)
|
||||
}
|
||||
|
||||
10
examples/websocket/e2e/tests/fixtures/find.rs
vendored
10
examples/websocket/e2e/tests/fixtures/find.rs
vendored
@@ -9,3 +9,13 @@ pub async fn input(client: &Client) -> Element {
|
||||
|
||||
textbox
|
||||
}
|
||||
|
||||
pub async fn label(client: &Client) -> Element {
|
||||
let label = client
|
||||
.wait()
|
||||
.for_element(Locator::Css("p"))
|
||||
.await
|
||||
.expect("");
|
||||
|
||||
label
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ async fn i_open_the_app(world: &mut AppWorld) -> Result<()> {
|
||||
#[given(regex = "^I add a text as (.*)$")]
|
||||
async fn i_add_a_text(world: &mut AppWorld, text: String) -> Result<()> {
|
||||
let client = &world.client;
|
||||
action::fill_input(client, text.as_str()).await?;
|
||||
action::add_text(client, text.as_str()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ async fn i_see_the_label_of_the_input_is(
|
||||
world: &mut AppWorld,
|
||||
text: String,
|
||||
) -> Result<()> {
|
||||
sleep(Duration::from_millis(500)).await;
|
||||
sleep(Duration::from_millis(50)).await;
|
||||
let client = &world.client;
|
||||
check::text_on_element(client, "p", &text).await?;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ authors = ["Greg Johnston"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/leptos-rs/leptos"
|
||||
description = "Axum integrations for the Leptos web framework."
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
|
||||
@@ -99,7 +99,6 @@ trace-component-props = [
|
||||
"leptos_dom/trace-component-props",
|
||||
]
|
||||
delegation = ["tachys/delegation"]
|
||||
islands-router = ["tachys/mark_branches"]
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.4.1"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
((root, pkg_path, output_name, wasm_output_name) => {
|
||||
let MOST_RECENT_CHILDREN_CB = [];
|
||||
let MOST_RECENT_CHILDREN_CB;
|
||||
|
||||
function idle(c) {
|
||||
if ("requestIdleCallback" in window) {
|
||||
@@ -22,18 +22,12 @@
|
||||
traverse(child, children);
|
||||
}
|
||||
} else {
|
||||
if (tag === 'leptos-children') {
|
||||
MOST_RECENT_CHILDREN_CB.push(node.$$on_hydrate);
|
||||
for(const child of node.children) {
|
||||
traverse(child);
|
||||
};
|
||||
// un-set the "most recent children"
|
||||
MOST_RECENT_CHILDREN_CB.pop();
|
||||
} else {
|
||||
for(const child of node.children) {
|
||||
traverse(child);
|
||||
};
|
||||
if(tag === 'leptos-children') {
|
||||
MOST_RECENT_CHILDREN_CB = node.$$on_hydrate;
|
||||
}
|
||||
for(const child of node.children) {
|
||||
traverse(child);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,9 +37,8 @@
|
||||
function hydrateIsland(el, id, mod) {
|
||||
const islandFn = mod[id];
|
||||
if (islandFn) {
|
||||
const children_cb = MOST_RECENT_CHILDREN_CB[MOST_RECENT_CHILDREN_CB.length-1];
|
||||
if (children_cb) {
|
||||
children_cb();
|
||||
if (MOST_RECENT_CHILDREN_CB) {
|
||||
MOST_RECENT_CHILDREN_CB();
|
||||
}
|
||||
islandFn(el);
|
||||
} else {
|
||||
|
||||
@@ -17,10 +17,6 @@ window.addEventListener("popstate", async (ev) => {
|
||||
});
|
||||
|
||||
window.addEventListener("submit", async (ev) => {
|
||||
if (ev.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
const req = submitToReq(ev);
|
||||
if(!req) {
|
||||
return;
|
||||
@@ -198,15 +194,6 @@ function diffRange(oldDocument, oldRoot, newDocument, newRoot, oldEnd, newEnd) {
|
||||
else if (oldNode.nodeType === Node.TEXT_NODE) {
|
||||
oldNode.textContent = newNode.textContent;
|
||||
}
|
||||
// islands should not be diffed on the client, because we do not want to overwrite client-side state
|
||||
// but their children should be diffed still, because they could contain new server content
|
||||
else if (oldNode.nodeType === Node.ELEMENT_NODE && oldNode.tagName === "LEPTOS-ISLAND") {
|
||||
// TODO: diff the leptos-children
|
||||
|
||||
// skip over leptos-island otherwise
|
||||
oldDocWalker.nextSibling();
|
||||
newDocWalker.nextSibling();
|
||||
}
|
||||
// if it's an element, replace if it's a different tag, or update attributes
|
||||
else if (oldNode.nodeType === Node.ELEMENT_NODE) {
|
||||
diffElement(oldNode, newNode);
|
||||
|
||||
@@ -107,19 +107,21 @@ pub fn HydrationScripts(
|
||||
.unwrap_or_default();
|
||||
|
||||
let root = root.unwrap_or_default();
|
||||
view! {
|
||||
<link rel="modulepreload" href=format!("{root}/{pkg_path}/{js_file_name}.js") nonce=nonce.clone()/>
|
||||
<link
|
||||
rel="preload"
|
||||
href=format!("{root}/{pkg_path}/{wasm_file_name}.wasm")
|
||||
r#as="fetch"
|
||||
r#type="application/wasm"
|
||||
crossorigin=nonce.clone().unwrap_or_default()
|
||||
/>
|
||||
<script type="module" nonce=nonce>
|
||||
{format!("{script}({root:?}, {pkg_path:?}, {js_file_name:?}, {wasm_file_name:?});{islands_router}")}
|
||||
</script>
|
||||
}
|
||||
use_context::<IslandsRouterNavigation>().is_none().then(|| {
|
||||
view! {
|
||||
<link rel="modulepreload" href=format!("{root}/{pkg_path}/{js_file_name}.js") nonce=nonce.clone()/>
|
||||
<link
|
||||
rel="preload"
|
||||
href=format!("{root}/{pkg_path}/{wasm_file_name}.wasm")
|
||||
r#as="fetch"
|
||||
r#type="application/wasm"
|
||||
crossorigin=nonce.clone().unwrap_or_default()
|
||||
/>
|
||||
<script type="module" nonce=nonce>
|
||||
{format!("{script}({root:?}, {pkg_path:?}, {js_file_name:?}, {wasm_file_name:?});{islands_router}")}
|
||||
</script>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// If this is provided via context, it means that you are using the islands router and
|
||||
|
||||
@@ -359,11 +359,23 @@ impl ToTokens for Model {
|
||||
let component = if is_island {
|
||||
let hydrate_fn_name = hydrate_fn_name.as_ref().unwrap();
|
||||
quote! {
|
||||
::leptos::tachys::html::islands::Island::new(
|
||||
stringify!(#hydrate_fn_name),
|
||||
#component
|
||||
)
|
||||
#island_serialized_props
|
||||
{
|
||||
if ::leptos::context::use_context::<::leptos::reactive::owner::IsHydrating>()
|
||||
.map(|h| h.0)
|
||||
.unwrap_or(false) {
|
||||
::leptos::either::Either::Left(
|
||||
#component
|
||||
)
|
||||
} else {
|
||||
::leptos::either::Either::Right(
|
||||
::leptos::tachys::html::islands::Island::new(
|
||||
stringify!(#hydrate_fn_name),
|
||||
#component
|
||||
)
|
||||
#island_serialized_props
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
component
|
||||
|
||||
@@ -300,34 +300,6 @@ impl<T> LocalResource<T> {
|
||||
pub fn refetch(&self) {
|
||||
self.refetch.try_update(|n| *n += 1);
|
||||
}
|
||||
|
||||
/// Synchronously, reactively reads the current value of the resource and applies the function
|
||||
/// `f` to its value if it is `Some(_)`.
|
||||
#[track_caller]
|
||||
pub fn map<U>(&self, f: impl FnOnce(&T) -> U) -> Option<U>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
self.data.try_with(|n| n.as_ref().map(f))?
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> LocalResource<Result<T, E>>
|
||||
where
|
||||
T: 'static,
|
||||
E: Clone + 'static,
|
||||
{
|
||||
/// Applies the given function when a resource that returns `Result<T, E>`
|
||||
/// has resolved and loaded an `Ok(_)`, rather than requiring nested `.map()`
|
||||
/// calls over the `Option<Result<_, _>>` returned by the resource.
|
||||
///
|
||||
/// This is useful when used with features like server functions, in conjunction
|
||||
/// with `<ErrorBoundary/>` and `<Suspense/>`, when these other components are
|
||||
/// left to handle the `None` and `Err(_)` states.
|
||||
#[track_caller]
|
||||
pub fn and_then<U>(&self, f: impl FnOnce(&T) -> U) -> Option<Result<U, E>> {
|
||||
self.map(|data| data.as_ref().map(f).map_err(|e| e.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoFuture for LocalResource<T>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "leptos_meta"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
authors = ["Greg Johnston"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/leptos-rs/leptos"
|
||||
|
||||
@@ -7,9 +7,6 @@ use leptos::{
|
||||
/// Injects an [`HTMLLinkElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLinkElement) into the document
|
||||
/// head that loads a stylesheet from the URL given by the `href` property.
|
||||
///
|
||||
/// Note that this does *not* work with the `cargo-leptos` `hash-files` feature: if you are using file
|
||||
/// hashing, you should use [`HashedStylesheet`](crate::HashedStylesheet).
|
||||
///
|
||||
/// ```
|
||||
/// use leptos::prelude::*;
|
||||
/// use leptos_meta::*;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "reactive_graph"
|
||||
version = "0.2.1"
|
||||
version = "0.2.0-rc3"
|
||||
authors = ["Greg Johnston"]
|
||||
license = "MIT"
|
||||
readme = "../README.md"
|
||||
|
||||
@@ -236,11 +236,11 @@ pub fn provide_context<T: Send + Sync + 'static>(value: T) {
|
||||
///
|
||||
/// Effect::new(move |_| {
|
||||
/// // each use_context clones the value
|
||||
/// let value = use_context::<String>()
|
||||
/// .expect("could not find String in context");
|
||||
/// let value =
|
||||
/// use_context::<String>().expect("could not find i32 in context");
|
||||
/// assert_eq!(value, "foo");
|
||||
/// let value2 = use_context::<String>()
|
||||
/// .expect("could not find String in context");
|
||||
/// let value2 =
|
||||
/// use_context::<String>().expect("could not find i32 in context");
|
||||
/// assert_eq!(value2, "foo");
|
||||
/// });
|
||||
/// });
|
||||
@@ -284,11 +284,11 @@ pub fn use_context<T: Clone + 'static>() -> Option<T> {
|
||||
///
|
||||
/// Effect::new(move |_| {
|
||||
/// // each use_context clones the value
|
||||
/// let value = use_context::<String>()
|
||||
/// .expect("could not find String in context");
|
||||
/// let value =
|
||||
/// use_context::<String>().expect("could not find i32 in context");
|
||||
/// assert_eq!(value, "foo");
|
||||
/// let value2 = use_context::<String>()
|
||||
/// .expect("could not find String in context");
|
||||
/// let value2 =
|
||||
/// use_context::<String>().expect("could not find i32 in context");
|
||||
/// assert_eq!(value2, "foo");
|
||||
/// });
|
||||
/// });
|
||||
|
||||
@@ -26,7 +26,7 @@ use std::{
|
||||
/// to more complex data structures. Instead, it allows you to provide a signal-like API for wrapped types
|
||||
/// without exposing the original type directly to users.
|
||||
pub struct ArcMappedSignal<T> {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: &'static Location<'static>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
try_read_untracked: Arc<
|
||||
@@ -44,7 +44,7 @@ pub struct ArcMappedSignal<T> {
|
||||
impl<T> Clone for ArcMappedSignal<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: self.defined_at,
|
||||
try_read_untracked: self.try_read_untracked.clone(),
|
||||
try_write: self.try_write.clone(),
|
||||
@@ -67,7 +67,7 @@ impl<T> ArcMappedSignal<T> {
|
||||
U: Send + Sync + 'static,
|
||||
{
|
||||
Self {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: Location::caller(),
|
||||
try_read_untracked: {
|
||||
let this = inner.clone();
|
||||
@@ -110,7 +110,7 @@ impl<T> ArcMappedSignal<T> {
|
||||
impl<T> Debug for ArcMappedSignal<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut partial = f.debug_struct("ArcMappedSignal");
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
partial.field("defined_at", &self.defined_at);
|
||||
partial.finish()
|
||||
}
|
||||
@@ -118,11 +118,11 @@ impl<T> Debug for ArcMappedSignal<T> {
|
||||
|
||||
impl<T> DefinedAt for ArcMappedSignal<T> {
|
||||
fn defined_at(&self) -> Option<&'static Location<'static>> {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
Some(self.defined_at)
|
||||
}
|
||||
#[cfg(not(any(debug_assertions, leptos_debuginfo)))]
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
None
|
||||
}
|
||||
@@ -228,7 +228,7 @@ where
|
||||
/// to more complex data structures. Instead, it allows you to provide a signal-like API for wrapped types
|
||||
/// without exposing the original type directly to users.
|
||||
pub struct MappedSignal<T, S = SyncStorage> {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: &'static Location<'static>,
|
||||
inner: StoredValue<ArcMappedSignal<T>, S>,
|
||||
}
|
||||
@@ -246,7 +246,7 @@ impl<T> MappedSignal<T> {
|
||||
U: Send + Sync + 'static,
|
||||
{
|
||||
Self {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: Location::caller(),
|
||||
inner: {
|
||||
let this = ArcRwSignal::from(inner);
|
||||
@@ -269,7 +269,7 @@ impl<T> Clone for MappedSignal<T> {
|
||||
impl<T> Debug for MappedSignal<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut partial = f.debug_struct("MappedSignal");
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
partial.field("defined_at", &self.defined_at);
|
||||
partial.finish()
|
||||
}
|
||||
@@ -277,11 +277,11 @@ impl<T> Debug for MappedSignal<T> {
|
||||
|
||||
impl<T> DefinedAt for MappedSignal<T> {
|
||||
fn defined_at(&self) -> Option<&'static Location<'static>> {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
Some(self.defined_at)
|
||||
}
|
||||
#[cfg(not(any(debug_assertions, leptos_debuginfo)))]
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
None
|
||||
}
|
||||
@@ -352,7 +352,7 @@ where
|
||||
#[track_caller]
|
||||
fn from(value: ArcMappedSignal<T>) -> Self {
|
||||
MappedSignal {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: Location::caller(),
|
||||
inner: StoredValue::new(value),
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ where
|
||||
#[track_caller]
|
||||
fn from(value: ArcWriteSignal<T>) -> Self {
|
||||
WriteSignal {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: Location::caller(),
|
||||
inner: ArenaItem::new_with_storage(value),
|
||||
}
|
||||
@@ -132,7 +132,7 @@ where
|
||||
#[track_caller]
|
||||
fn from_local(value: ArcWriteSignal<T>) -> Self {
|
||||
WriteSignal {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: Location::caller(),
|
||||
inner: ArenaItem::new_with_storage(value),
|
||||
}
|
||||
|
||||
@@ -11,8 +11,7 @@ pub mod read {
|
||||
},
|
||||
signal::{
|
||||
guards::{Mapped, Plain, ReadGuard},
|
||||
ArcMappedSignal, ArcReadSignal, ArcRwSignal, MappedSignal,
|
||||
ReadSignal, RwSignal,
|
||||
ArcReadSignal, ArcRwSignal, ReadSignal, RwSignal,
|
||||
},
|
||||
traits::{
|
||||
DefinedAt, Dispose, Get, Read, ReadUntracked, ReadValue, Track,
|
||||
@@ -808,16 +807,6 @@ pub mod read {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<MappedSignal<T>> for Signal<T>
|
||||
where
|
||||
T: Clone + Send + Sync + 'static,
|
||||
{
|
||||
#[track_caller]
|
||||
fn from(value: MappedSignal<T>) -> Self {
|
||||
Self::derive(move || value.get())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<RwSignal<T, LocalStorage>> for Signal<T, LocalStorage>
|
||||
where
|
||||
T: 'static,
|
||||
@@ -850,16 +839,6 @@ pub mod read {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<ArcMappedSignal<T>> for Signal<T>
|
||||
where
|
||||
T: Clone + Send + Sync + 'static,
|
||||
{
|
||||
#[track_caller]
|
||||
fn from(value: ArcMappedSignal<T>) -> Self {
|
||||
MappedSignal::from(value).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<ArcRwSignal<T>> for Signal<T, LocalStorage>
|
||||
where
|
||||
T: Send + Sync + 'static,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "reactive_stores"
|
||||
version = "0.2.1"
|
||||
version = "0.2.0-rc3"
|
||||
authors = ["Greg Johnston"]
|
||||
license = "MIT"
|
||||
readme = "../README.md"
|
||||
|
||||
@@ -39,7 +39,7 @@ where
|
||||
#[track_caller]
|
||||
fn deref_field(self) -> DerefedField<Self> {
|
||||
DerefedField {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: Location::caller(),
|
||||
inner: self,
|
||||
}
|
||||
@@ -51,7 +51,7 @@ where
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct DerefedField<S> {
|
||||
inner: S,
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: &'static Location<'static>,
|
||||
}
|
||||
|
||||
@@ -92,11 +92,11 @@ where
|
||||
<S::Value as Deref>::Target: Sized + 'static,
|
||||
{
|
||||
fn defined_at(&self) -> Option<&'static Location<'static>> {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
Some(self.defined_at)
|
||||
}
|
||||
#[cfg(not(any(debug_assertions, leptos_debuginfo)))]
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
None
|
||||
}
|
||||
|
||||
@@ -56,12 +56,12 @@
|
||||
//!
|
||||
//! # if false { // don't run effect in doctests
|
||||
//! Effect::new(move |_| {
|
||||
//! // you can access individual store fields with a getter
|
||||
//! // you can access individual store withs field a getter
|
||||
//! println!("todos: {:?}", &*store.todos().read());
|
||||
//! });
|
||||
//! # }
|
||||
//!
|
||||
//! // won't notify the effect that listens to `todos`
|
||||
//! // won't notify the effect that listen to `todos`
|
||||
//! store.todos().write().push(Todo {
|
||||
//! label: "Test".to_string(),
|
||||
//! completed: false,
|
||||
@@ -69,7 +69,7 @@
|
||||
//! ```
|
||||
//! ### Generated traits
|
||||
//! The [`Store`](macro@Store) macro generates traits for each `struct` to which it is applied. When working
|
||||
//! within a single file or module, this is not an issue. However, when working with multiple modules
|
||||
//! within a single file more module, this is not an issue. However, when working with multiple modules
|
||||
//! or files, one needs to `use` the generated traits. The general pattern is that for each `struct`
|
||||
//! named `Foo`, the macro generates a trait named `FooStoreFields`. For example:
|
||||
//! ```rust
|
||||
@@ -608,14 +608,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> PartialEq for Store<T, S> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner == other.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> Eq for Store<T, S> {}
|
||||
|
||||
impl<T> Store<T, LocalStorage>
|
||||
where
|
||||
T: 'static,
|
||||
@@ -767,7 +759,7 @@ where
|
||||
{
|
||||
fn from(value: ArcStore<T>) -> Self {
|
||||
Self {
|
||||
#[cfg(any(debug_assertions, leptos_debuginfo))]
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: value.defined_at,
|
||||
inner: ArenaItem::new_with_storage(value),
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "reactive_stores_macro"
|
||||
version = "0.2.1"
|
||||
version = "0.2.0-rc3"
|
||||
authors = ["Greg Johnston"]
|
||||
license = "MIT"
|
||||
readme = "../README.md"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "leptos_router"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
authors = ["Greg Johnston", "Ben Wishovich"]
|
||||
license = "MIT"
|
||||
readme = "../README.md"
|
||||
|
||||
@@ -418,7 +418,7 @@ impl RenderHtml for MatchedRoute {
|
||||
mark_branches: bool,
|
||||
extra_attrs: Vec<AnyAttribute>,
|
||||
) {
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch(&self.0);
|
||||
}
|
||||
self.1.to_html_with_buf(
|
||||
@@ -428,11 +428,8 @@ impl RenderHtml for MatchedRoute {
|
||||
mark_branches,
|
||||
extra_attrs,
|
||||
);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch(&self.0);
|
||||
if *position == Position::NextChildAfterText {
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,7 +443,7 @@ impl RenderHtml for MatchedRoute {
|
||||
) where
|
||||
Self: Sized,
|
||||
{
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch(&self.0);
|
||||
}
|
||||
self.1.to_html_async_with_buf::<OUT_OF_ORDER>(
|
||||
@@ -456,11 +453,8 @@ impl RenderHtml for MatchedRoute {
|
||||
mark_branches,
|
||||
extra_attrs,
|
||||
);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch(&self.0);
|
||||
if *position == Position::NextChildAfterText {
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "leptos_router_macro"
|
||||
version = "0.8.1"
|
||||
version = "0.8.0-rc3"
|
||||
authors = ["Greg Johnston", "Ben Wishovich"]
|
||||
license = "MIT"
|
||||
readme = "../README.md"
|
||||
|
||||
@@ -16,7 +16,7 @@ server_fn_macro_default = { workspace = true }
|
||||
const_format = "0.2.33"
|
||||
const-str = "0.6.2"
|
||||
xxhash-rust = { version = "0.8.12", features = ["const_xxh64"] }
|
||||
rustversion = { workspace = true }
|
||||
rustversion = { workspace = true}
|
||||
# used across multiple features
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
send_wrapper = { version = "0.6.0", features = ["futures"], optional = true }
|
||||
@@ -82,9 +82,6 @@ url = "2"
|
||||
pin-project-lite = "0.2.15"
|
||||
tokio = { version = "1.43.0", features = ["rt"], optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.4.1"
|
||||
|
||||
[dev-dependencies]
|
||||
trybuild = { workspace = true }
|
||||
|
||||
@@ -241,7 +238,4 @@ skip_feature_sets = [
|
||||
max_combination_size = 2
|
||||
|
||||
[lints.rust]
|
||||
unexpected_cfgs = { level = "warn", check-cfg = [
|
||||
'cfg(leptos_debuginfo)',
|
||||
'cfg(rustc_nightly)',
|
||||
] }
|
||||
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(leptos_debuginfo)'] }
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
use rustc_version::{version_meta, Channel};
|
||||
|
||||
fn main() {
|
||||
// Set cfg flags depending on release channel
|
||||
if matches!(version_meta().unwrap().channel, Channel::Nightly) {
|
||||
println!("cargo:rustc-cfg=rustc_nightly");
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,11 @@ error[E0271]: expected `impl Future<Output = ()>` to be a future that resolves t
|
||||
|
|
||||
= note: expected enum `Result<_, _>`
|
||||
found unit type `()`
|
||||
note: required by a bound in `ServerFn::{anon_assoc#0}`
|
||||
note: required by a bound in `ServerFn::{synthetic#0}`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| ) -> impl Future<Output = Result<Self::Output, Self::Error>> + Send;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ServerFn::{anon_assoc#0}`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ServerFn::{synthetic#0}`
|
||||
|
||||
error[E0277]: () is not a `Result` or aliased `Result`. Server functions must return a `Result` or aliased `Result`.
|
||||
--> tests/invalid/empty_return.rs:3:1
|
||||
|
||||
@@ -16,11 +16,11 @@ error[E0271]: expected `impl Future<Output = CustomError>` to be a future that r
|
||||
|
|
||||
= note: expected enum `Result<_, _>`
|
||||
found enum `CustomError`
|
||||
note: required by a bound in `ServerFn::{anon_assoc#0}`
|
||||
note: required by a bound in `ServerFn::{synthetic#0}`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| ) -> impl Future<Output = Result<Self::Output, Self::Error>> + Send;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ServerFn::{anon_assoc#0}`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ServerFn::{synthetic#0}`
|
||||
|
||||
error[E0277]: CustomError is not a `Result` or aliased `Result`. Server functions must return a `Result` or aliased `Result`.
|
||||
--> tests/invalid/not_result.rs:25:1
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// multiple combinations of features are tested. This ensures this file is only
|
||||
// run when **only** the browser feature is enabled.
|
||||
#![cfg(all(
|
||||
rustc_nightly,
|
||||
feature = "browser",
|
||||
not(any(
|
||||
feature = "postcard",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tachys"
|
||||
version = "0.2.1"
|
||||
version = "0.2.0-rc3"
|
||||
authors = ["Greg Johnston"]
|
||||
license = "MIT"
|
||||
readme = "../README.md"
|
||||
@@ -186,7 +186,6 @@ reactive_graph = ["dep:reactive_graph", "dep:any_spawner"]
|
||||
reactive_stores = ["reactive_graph", "dep:reactive_stores"]
|
||||
sledgehammer = ["dep:sledgehammer_bindgen", "dep:sledgehammer_utils"]
|
||||
tracing = ["dep:tracing"]
|
||||
mark_branches = []
|
||||
|
||||
[package.metadata.cargo-all-features]
|
||||
denylist = ["tracing", "sledgehammer"]
|
||||
|
||||
@@ -8,7 +8,6 @@ use crate::{
|
||||
|
||||
/// An island of interactivity in an otherwise-inert HTML document.
|
||||
pub struct Island<View> {
|
||||
has_element_representation: bool,
|
||||
component: &'static str,
|
||||
props_json: String,
|
||||
view: View,
|
||||
@@ -20,8 +19,6 @@ impl<View> Island<View> {
|
||||
/// Creates a new island with the given component name.
|
||||
pub fn new(component: &'static str, view: View) -> Self {
|
||||
Island {
|
||||
has_element_representation:
|
||||
Self::should_have_element_representation(),
|
||||
component,
|
||||
props_json: String::new(),
|
||||
view,
|
||||
@@ -54,21 +51,6 @@ impl<View> Island<View> {
|
||||
buf.push_str(ISLAND_TAG);
|
||||
buf.push('>');
|
||||
}
|
||||
|
||||
/// Whether this island should be represented by an actual HTML element
|
||||
fn should_have_element_representation() -> bool {
|
||||
#[cfg(feature = "reactive_graph")]
|
||||
{
|
||||
use reactive_graph::owner::{use_context, IsHydrating};
|
||||
let already_hydrating =
|
||||
use_context::<IsHydrating>().map(|h| h.0).unwrap_or(false);
|
||||
!already_hydrating
|
||||
}
|
||||
#[cfg(not(feature = "reactive_graph"))]
|
||||
{
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<View> Render for Island<View>
|
||||
@@ -101,13 +83,11 @@ where
|
||||
Self::Output<NewAttr>: RenderHtml,
|
||||
{
|
||||
let Island {
|
||||
has_element_representation,
|
||||
component,
|
||||
props_json,
|
||||
view,
|
||||
} = self;
|
||||
Island {
|
||||
has_element_representation,
|
||||
component,
|
||||
props_json,
|
||||
view: view.add_any_attr(attr),
|
||||
@@ -134,13 +114,11 @@ where
|
||||
|
||||
async fn resolve(self) -> Self::AsyncOutput {
|
||||
let Island {
|
||||
has_element_representation,
|
||||
component,
|
||||
props_json,
|
||||
view,
|
||||
} = self;
|
||||
Island {
|
||||
has_element_representation,
|
||||
component,
|
||||
props_json,
|
||||
view: view.resolve().await,
|
||||
@@ -155,10 +133,7 @@ where
|
||||
mark_branches: bool,
|
||||
extra_attrs: Vec<AnyAttribute>,
|
||||
) {
|
||||
let has_element = self.has_element_representation;
|
||||
if has_element {
|
||||
Self::open_tag(self.component, &self.props_json, buf);
|
||||
}
|
||||
Self::open_tag(self.component, &self.props_json, buf);
|
||||
self.view.to_html_with_buf(
|
||||
buf,
|
||||
position,
|
||||
@@ -166,9 +141,7 @@ where
|
||||
mark_branches,
|
||||
extra_attrs,
|
||||
);
|
||||
if has_element {
|
||||
Self::close_tag(buf);
|
||||
}
|
||||
Self::close_tag(buf);
|
||||
}
|
||||
|
||||
fn to_html_async_with_buf<const OUT_OF_ORDER: bool>(
|
||||
@@ -181,12 +154,9 @@ where
|
||||
) where
|
||||
Self: Sized,
|
||||
{
|
||||
let has_element = self.has_element_representation;
|
||||
// insert the opening tag synchronously
|
||||
let mut tag = String::new();
|
||||
if has_element {
|
||||
Self::open_tag(self.component, &self.props_json, &mut tag);
|
||||
}
|
||||
Self::open_tag(self.component, &self.props_json, &mut tag);
|
||||
buf.push_sync(&tag);
|
||||
|
||||
// streaming render for the view
|
||||
@@ -200,9 +170,7 @@ where
|
||||
|
||||
// and insert the closing tag synchronously
|
||||
tag.clear();
|
||||
if has_element {
|
||||
Self::close_tag(&mut tag);
|
||||
}
|
||||
Self::close_tag(&mut tag);
|
||||
buf.push_sync(&tag);
|
||||
}
|
||||
|
||||
@@ -211,21 +179,18 @@ where
|
||||
cursor: &Cursor,
|
||||
position: &PositionState,
|
||||
) -> Self::State {
|
||||
if self.has_element_representation {
|
||||
if position.get() == Position::FirstChild {
|
||||
cursor.child();
|
||||
} else if position.get() == Position::NextChild {
|
||||
cursor.sibling();
|
||||
}
|
||||
position.set(Position::FirstChild);
|
||||
if position.get() == Position::FirstChild {
|
||||
cursor.child();
|
||||
} else if position.get() == Position::NextChild {
|
||||
cursor.sibling();
|
||||
}
|
||||
position.set(Position::FirstChild);
|
||||
|
||||
self.view.hydrate::<FROM_SERVER>(cursor, position)
|
||||
}
|
||||
|
||||
fn into_owned(self) -> Self::Owned {
|
||||
Island {
|
||||
has_element_representation: self.has_element_representation,
|
||||
component: self.component,
|
||||
props_json: self.props_json,
|
||||
view: self.view.into_owned(),
|
||||
@@ -393,7 +358,6 @@ where
|
||||
} else if curr_position != Position::Current {
|
||||
cursor.sibling();
|
||||
}
|
||||
position.set(Position::NextChild);
|
||||
|
||||
if let Some(on_hydrate) = self.on_hydrate {
|
||||
use crate::{
|
||||
|
||||
@@ -84,27 +84,22 @@ where
|
||||
*self.0.borrow_mut() = node;
|
||||
}
|
||||
|
||||
/// Advances to the next placeholder node and returns it
|
||||
/// Advances to the next placeholder node.
|
||||
pub fn next_placeholder(
|
||||
&self,
|
||||
position: &PositionState,
|
||||
) -> crate::renderer::types::Placeholder {
|
||||
//crate::dom::log("looking for placeholder after");
|
||||
//Rndr::log_node(&self.current());
|
||||
self.advance_to_placeholder(position);
|
||||
let marker = self.current();
|
||||
crate::renderer::types::Placeholder::cast_from(marker.clone())
|
||||
.unwrap_or_else(|| failed_to_cast_marker_node(marker))
|
||||
}
|
||||
|
||||
/// Advances to the next placeholder node.
|
||||
pub fn advance_to_placeholder(&self, position: &PositionState) {
|
||||
if position.get() == Position::FirstChild {
|
||||
self.child();
|
||||
} else {
|
||||
self.sibling();
|
||||
}
|
||||
let marker = self.current();
|
||||
position.set(Position::NextChild);
|
||||
crate::renderer::types::Placeholder::cast_from(marker.clone())
|
||||
.unwrap_or_else(|| failed_to_cast_marker_node(marker))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -285,15 +285,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for RenderEffectState<T> {
|
||||
fn drop(&mut self) {
|
||||
if let Some(effect) = self.0.take() {
|
||||
drop(effect.take_value());
|
||||
drop(effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<M, E> Mountable for Result<M, E>
|
||||
where
|
||||
M: Mountable,
|
||||
|
||||
@@ -223,20 +223,10 @@ impl StreamBuilder {
|
||||
);
|
||||
}
|
||||
let chunks = subbuilder.finish().take_chunks();
|
||||
let mut flattened_chunks =
|
||||
VecDeque::with_capacity(chunks.len());
|
||||
for chunk in chunks {
|
||||
// this will wait for any ErrorBoundary async nodes and flatten them out
|
||||
if let StreamChunk::Async { chunks } = chunk {
|
||||
flattened_chunks.extend(chunks.await);
|
||||
} else {
|
||||
flattened_chunks.push_back(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
OooChunk {
|
||||
id,
|
||||
chunks: flattened_chunks,
|
||||
chunks,
|
||||
replace,
|
||||
nonce,
|
||||
}
|
||||
|
||||
@@ -392,12 +392,10 @@ impl RenderHtml for AnyView {
|
||||
) {
|
||||
#[cfg(feature = "ssr")]
|
||||
{
|
||||
let type_id = if mark_branches && escape {
|
||||
format!("{:?}", self.type_id)
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
if mark_branches && escape {
|
||||
let type_id = mark_branches
|
||||
.then(|| format!("{:?}", self.type_id))
|
||||
.unwrap_or_default();
|
||||
if mark_branches {
|
||||
buf.open_branch(&type_id);
|
||||
}
|
||||
(self.to_html)(
|
||||
@@ -408,11 +406,8 @@ impl RenderHtml for AnyView {
|
||||
mark_branches,
|
||||
extra_attrs,
|
||||
);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch(&type_id);
|
||||
if *position == Position::NextChildAfterText {
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
@@ -441,14 +436,6 @@ impl RenderHtml for AnyView {
|
||||
{
|
||||
#[cfg(feature = "ssr")]
|
||||
if OUT_OF_ORDER {
|
||||
let type_id = if mark_branches && escape {
|
||||
format!("{:?}", self.type_id)
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
if mark_branches && escape {
|
||||
buf.open_branch(&type_id);
|
||||
}
|
||||
(self.to_html_async_ooo)(
|
||||
self.value,
|
||||
buf,
|
||||
@@ -457,19 +444,11 @@ impl RenderHtml for AnyView {
|
||||
mark_branches,
|
||||
extra_attrs,
|
||||
);
|
||||
if mark_branches && escape {
|
||||
buf.close_branch(&type_id);
|
||||
if *position == Position::NextChildAfterText {
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let type_id = if mark_branches && escape {
|
||||
format!("{:?}", self.type_id)
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
if mark_branches && escape {
|
||||
let type_id = mark_branches
|
||||
.then(|| format!("{:?}", self.type_id))
|
||||
.unwrap_or_default();
|
||||
if mark_branches {
|
||||
buf.open_branch(&type_id);
|
||||
}
|
||||
(self.to_html_async)(
|
||||
@@ -480,11 +459,8 @@ impl RenderHtml for AnyView {
|
||||
mark_branches,
|
||||
extra_attrs,
|
||||
);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch(&type_id);
|
||||
if *position == Position::NextChildAfterText {
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
@@ -507,23 +483,13 @@ impl RenderHtml for AnyView {
|
||||
position: &PositionState,
|
||||
) -> Self::State {
|
||||
#[cfg(feature = "hydrate")]
|
||||
{
|
||||
if FROM_SERVER {
|
||||
if cfg!(feature = "mark_branches") {
|
||||
cursor.advance_to_placeholder(position);
|
||||
}
|
||||
let state =
|
||||
(self.hydrate_from_server)(self.value, cursor, position);
|
||||
if cfg!(feature = "mark_branches") {
|
||||
cursor.advance_to_placeholder(position);
|
||||
}
|
||||
state
|
||||
} else {
|
||||
panic!(
|
||||
"hydrating AnyView from inside a ViewTemplate is not \
|
||||
supported."
|
||||
);
|
||||
}
|
||||
if FROM_SERVER {
|
||||
(self.hydrate_from_server)(self.value, cursor, position)
|
||||
} else {
|
||||
panic!(
|
||||
"hydrating AnyView from inside a ViewTemplate is not \
|
||||
supported."
|
||||
);
|
||||
}
|
||||
#[cfg(not(feature = "hydrate"))]
|
||||
{
|
||||
|
||||
@@ -308,7 +308,7 @@ where
|
||||
) {
|
||||
match self {
|
||||
Either::Left(left) => {
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch("0");
|
||||
}
|
||||
left.to_html_with_buf(
|
||||
@@ -318,15 +318,12 @@ where
|
||||
mark_branches,
|
||||
extra_attrs,
|
||||
);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch("0");
|
||||
if *position == Position::NextChildAfterText {
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
Either::Right(right) => {
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch("1");
|
||||
}
|
||||
right.to_html_with_buf(
|
||||
@@ -336,11 +333,8 @@ where
|
||||
mark_branches,
|
||||
extra_attrs,
|
||||
);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch("1");
|
||||
if *position == Position::NextChildAfterText {
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,7 +352,7 @@ where
|
||||
{
|
||||
match self {
|
||||
Either::Left(left) => {
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch("0");
|
||||
}
|
||||
left.to_html_async_with_buf::<OUT_OF_ORDER>(
|
||||
@@ -368,15 +362,12 @@ where
|
||||
mark_branches,
|
||||
extra_attrs,
|
||||
);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch("0");
|
||||
if *position == Position::NextChildAfterText {
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
Either::Right(right) => {
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch("1");
|
||||
}
|
||||
right.to_html_async_with_buf::<OUT_OF_ORDER>(
|
||||
@@ -386,11 +377,8 @@ where
|
||||
mark_branches,
|
||||
extra_attrs,
|
||||
);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch("1");
|
||||
if *position == Position::NextChildAfterText {
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -401,21 +389,14 @@ where
|
||||
cursor: &Cursor,
|
||||
position: &PositionState,
|
||||
) -> Self::State {
|
||||
if cfg!(feature = "mark_branches") {
|
||||
cursor.advance_to_placeholder(position);
|
||||
}
|
||||
let state = match self {
|
||||
match self {
|
||||
Either::Left(left) => {
|
||||
Either::Left(left.hydrate::<FROM_SERVER>(cursor, position))
|
||||
}
|
||||
Either::Right(right) => {
|
||||
Either::Right(right.hydrate::<FROM_SERVER>(cursor, position))
|
||||
}
|
||||
};
|
||||
if cfg!(feature = "mark_branches") {
|
||||
cursor.advance_to_placeholder(position);
|
||||
}
|
||||
state
|
||||
}
|
||||
|
||||
fn into_owned(self) -> Self::Owned {
|
||||
@@ -868,15 +849,12 @@ macro_rules! tuples {
|
||||
) {
|
||||
match self {
|
||||
$([<EitherOf $num>]::$ty(this) => {
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch(stringify!($ty));
|
||||
}
|
||||
this.to_html_with_buf(buf, position, escape, mark_branches, extra_attrs);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch(stringify!($ty));
|
||||
if *position == Position::NextChildAfterText {
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
})*
|
||||
}
|
||||
@@ -894,15 +872,12 @@ macro_rules! tuples {
|
||||
{
|
||||
match self {
|
||||
$([<EitherOf $num>]::$ty(this) => {
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch(stringify!($ty));
|
||||
}
|
||||
this.to_html_async_with_buf::<OUT_OF_ORDER>(buf, position, escape, mark_branches, extra_attrs);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch(stringify!($ty));
|
||||
if *position == Position::NextChildAfterText {
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
})*
|
||||
}
|
||||
@@ -913,17 +888,11 @@ macro_rules! tuples {
|
||||
cursor: &Cursor,
|
||||
position: &PositionState,
|
||||
) -> Self::State {
|
||||
if cfg!(feature = "mark_branches") {
|
||||
cursor.advance_to_placeholder(position);
|
||||
}
|
||||
let state = match self {
|
||||
$([<EitherOf $num>]::$ty(this) => {
|
||||
[<EitherOf $num>]::$ty(this.hydrate::<FROM_SERVER>(cursor, position))
|
||||
})*
|
||||
};
|
||||
if cfg!(feature = "mark_branches") {
|
||||
cursor.advance_to_placeholder(position);
|
||||
}
|
||||
|
||||
Self::State { state }
|
||||
}
|
||||
|
||||
@@ -33,10 +33,11 @@ where
|
||||
match (&mut state.state, self) {
|
||||
// both errors: throw the new error and replace
|
||||
(Either::Right(_), Err(new)) => {
|
||||
if let Some(old_error) = state.error.take() {
|
||||
if let Some(old_error) =
|
||||
state.error.replace(throw_error::throw(new.into()))
|
||||
{
|
||||
throw_error::clear(&old_error);
|
||||
}
|
||||
state.error = Some(throw_error::throw(new.into()));
|
||||
}
|
||||
// both Ok: need to rebuild child
|
||||
(Either::Left(old), Ok(new)) => {
|
||||
|
||||
@@ -435,7 +435,7 @@ where
|
||||
T: Mountable,
|
||||
{
|
||||
states: Vec<T>,
|
||||
marker: crate::renderer::types::Placeholder,
|
||||
parent: Option<crate::renderer::types::Element>,
|
||||
}
|
||||
|
||||
impl<T> Mountable for StaticVecState<T>
|
||||
@@ -443,10 +443,7 @@ where
|
||||
T: Mountable,
|
||||
{
|
||||
fn unmount(&mut self) {
|
||||
for state in self.states.iter_mut() {
|
||||
state.unmount();
|
||||
}
|
||||
self.marker.unmount();
|
||||
self.states.iter_mut().for_each(Mountable::unmount);
|
||||
}
|
||||
|
||||
fn mount(
|
||||
@@ -457,7 +454,7 @@ where
|
||||
for state in self.states.iter_mut() {
|
||||
state.mount(parent, marker);
|
||||
}
|
||||
self.marker.mount(parent, marker);
|
||||
self.parent = Some(parent.clone());
|
||||
}
|
||||
|
||||
fn insert_before_this(&self, child: &mut dyn Mountable) -> bool {
|
||||
@@ -466,7 +463,7 @@ where
|
||||
return true;
|
||||
}
|
||||
}
|
||||
self.marker.insert_before_this(child)
|
||||
false
|
||||
}
|
||||
|
||||
fn elements(&self) -> Vec<crate::renderer::types::Element> {
|
||||
@@ -484,52 +481,27 @@ where
|
||||
type State = StaticVecState<T::State>;
|
||||
|
||||
fn build(self) -> Self::State {
|
||||
let marker = Rndr::create_placeholder();
|
||||
Self::State {
|
||||
states: self.0.into_iter().map(T::build).collect(),
|
||||
marker,
|
||||
parent: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn rebuild(self, state: &mut Self::State) {
|
||||
let StaticVecState { states, marker } = state;
|
||||
let old = states;
|
||||
let Self::State { states, .. } = state;
|
||||
|
||||
// reuses the Vec impl
|
||||
if old.is_empty() {
|
||||
let mut new = self.build().states;
|
||||
for item in new.iter_mut() {
|
||||
Rndr::mount_before(item, marker.as_ref());
|
||||
}
|
||||
*old = new;
|
||||
} else if self.0.is_empty() {
|
||||
// TODO fast path for clearing
|
||||
for item in old.iter_mut() {
|
||||
item.unmount();
|
||||
}
|
||||
old.clear();
|
||||
} else {
|
||||
let mut adds = vec![];
|
||||
let mut removes_at_end = 0;
|
||||
for item in self.0.into_iter().zip_longest(old.iter_mut()) {
|
||||
match item {
|
||||
itertools::EitherOrBoth::Both(new, old) => {
|
||||
T::rebuild(new, old)
|
||||
}
|
||||
itertools::EitherOrBoth::Left(new) => {
|
||||
let mut new_state = new.build();
|
||||
Rndr::mount_before(&mut new_state, marker.as_ref());
|
||||
adds.push(new_state);
|
||||
}
|
||||
itertools::EitherOrBoth::Right(old) => {
|
||||
removes_at_end += 1;
|
||||
old.unmount()
|
||||
}
|
||||
}
|
||||
}
|
||||
old.truncate(old.len() - removes_at_end);
|
||||
old.append(&mut adds);
|
||||
// StaticVec's in general shouldn't need to be reused, but rebuild() will still trigger e.g. if 2 routes have the same tree,
|
||||
// this can cause problems if differing in lengths. Because we don't use marker nodes in StaticVec, we rebuild the entire vec remounting to the parent.
|
||||
|
||||
for state in states {
|
||||
state.unmount();
|
||||
}
|
||||
let parent = state
|
||||
.parent
|
||||
.take()
|
||||
.expect("parent should always be Some() on a StaticVec rebuild()");
|
||||
*state = self.build();
|
||||
state.mount(&parent, None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,7 +552,7 @@ where
|
||||
}
|
||||
|
||||
fn html_len(&self) -> usize {
|
||||
self.0.iter().map(RenderHtml::html_len).sum::<usize>() + 3
|
||||
self.0.iter().map(RenderHtml::html_len).sum::<usize>()
|
||||
}
|
||||
|
||||
fn to_html_with_buf(
|
||||
@@ -600,10 +572,6 @@ where
|
||||
extra_attrs.clone(),
|
||||
);
|
||||
}
|
||||
if escape {
|
||||
buf.push_str("<!>");
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
|
||||
fn to_html_async_with_buf<const OUT_OF_ORDER: bool>(
|
||||
@@ -625,10 +593,6 @@ where
|
||||
extra_attrs.clone(),
|
||||
);
|
||||
}
|
||||
if escape {
|
||||
buf.push_sync("<!>");
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
}
|
||||
|
||||
fn hydrate<const FROM_SERVER: bool>(
|
||||
@@ -641,11 +605,8 @@ where
|
||||
.into_iter()
|
||||
.map(|child| child.hydrate::<FROM_SERVER>(cursor, position))
|
||||
.collect();
|
||||
|
||||
let marker = cursor.next_placeholder(position);
|
||||
position.set(Position::NextChild);
|
||||
|
||||
Self::State { states, marker }
|
||||
let parent = cursor.current().parent_element();
|
||||
Self::State { states, parent }
|
||||
}
|
||||
|
||||
fn into_owned(self) -> Self::Owned {
|
||||
|
||||
@@ -252,12 +252,12 @@ where
|
||||
mark_branches: bool,
|
||||
extra_attrs: Vec<AnyAttribute>,
|
||||
) {
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch("for");
|
||||
}
|
||||
for (index, item) in self.items.into_iter().enumerate() {
|
||||
let (_, item) = (self.view_fn)(index, item);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch("item");
|
||||
}
|
||||
item.to_html_with_buf(
|
||||
@@ -267,12 +267,12 @@ where
|
||||
mark_branches,
|
||||
extra_attrs.clone(),
|
||||
);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch("item");
|
||||
}
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch("for");
|
||||
}
|
||||
buf.push_str("<!>");
|
||||
@@ -286,7 +286,7 @@ where
|
||||
mark_branches: bool,
|
||||
extra_attrs: Vec<AnyAttribute>,
|
||||
) {
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch("for");
|
||||
}
|
||||
for (index, item) in self.items.into_iter().enumerate() {
|
||||
@@ -296,7 +296,7 @@ where
|
||||
format!("item-{key}")
|
||||
});
|
||||
let (_, item) = (self.view_fn)(index, item);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.open_branch(branch_name.as_ref().unwrap());
|
||||
}
|
||||
item.to_html_async_with_buf::<OUT_OF_ORDER>(
|
||||
@@ -306,12 +306,12 @@ where
|
||||
mark_branches,
|
||||
extra_attrs.clone(),
|
||||
);
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch(branch_name.as_ref().unwrap());
|
||||
}
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
if mark_branches && escape {
|
||||
if mark_branches {
|
||||
buf.close_branch("for");
|
||||
}
|
||||
buf.push_sync("<!>");
|
||||
@@ -322,10 +322,6 @@ where
|
||||
cursor: &Cursor,
|
||||
position: &PositionState,
|
||||
) -> Self::State {
|
||||
if cfg!(feature = "mark_branches") {
|
||||
cursor.advance_to_placeholder(position);
|
||||
}
|
||||
|
||||
// get parent and position
|
||||
let current = cursor.current();
|
||||
let parent = if position.get() == Position::FirstChild {
|
||||
@@ -346,22 +342,11 @@ where
|
||||
for (index, item) in items.enumerate() {
|
||||
hashed_items.insert((self.key_fn)(&item));
|
||||
let (set_index, view) = (self.view_fn)(index, item);
|
||||
if cfg!(feature = "mark_branches") {
|
||||
cursor.advance_to_placeholder(position);
|
||||
}
|
||||
let item = view.hydrate::<FROM_SERVER>(cursor, position);
|
||||
if cfg!(feature = "mark_branches") {
|
||||
cursor.advance_to_placeholder(position);
|
||||
}
|
||||
rendered_items.push(Some((set_index, item)));
|
||||
}
|
||||
let marker = cursor.next_placeholder(position);
|
||||
position.set(Position::NextChild);
|
||||
|
||||
if cfg!(feature = "mark_branches") {
|
||||
cursor.advance_to_placeholder(position);
|
||||
}
|
||||
|
||||
KeyedState {
|
||||
parent: Some(parent),
|
||||
marker,
|
||||
|
||||
Reference in New Issue
Block a user