mirror of
https://github.com/leptos-rs/leptos.git
synced 2026-01-07 11:50:12 -05:00
Compare commits
12 Commits
4512
...
remove-par
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a90e45afd8 | ||
|
|
dd507168fa | ||
|
|
8438b1633f | ||
|
|
b87c310046 | ||
|
|
692153ded2 | ||
|
|
bbb4e698ba | ||
|
|
0c44199bc9 | ||
|
|
4f0daada69 | ||
|
|
b45eb8f39f | ||
|
|
46f16ec9cf | ||
|
|
bfdf0bf4d1 | ||
|
|
e7e18b1995 |
241
Cargo.lock
generated
241
Cargo.lock
generated
@@ -88,7 +88,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -205,7 +205,7 @@ dependencies = [
|
||||
"actix-router",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -296,9 +296,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "3.4.1"
|
||||
version = "3.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc"
|
||||
checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"event-listener-strategy",
|
||||
@@ -330,7 +330,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -347,7 +347,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -376,7 +376,7 @@ dependencies = [
|
||||
"manyhow",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -392,7 +392,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"quote-use",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -403,9 +403,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.8.7"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b098575ebe77cb6d14fc7f32749631a6e44edbef6b796f89b020e99ba20d425"
|
||||
checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8"
|
||||
dependencies = [
|
||||
"axum-core",
|
||||
"base64",
|
||||
@@ -440,9 +440,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.5.5"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22"
|
||||
checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
@@ -490,7 +490,7 @@ checksum = "238b90427dfad9da4a9abd60f3ec1cdee6b80454bde49ed37f1781dd8e9dc7f9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -555,7 +555,7 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -599,9 +599,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.50"
|
||||
version = "1.2.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c"
|
||||
checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
@@ -882,29 +882,29 @@ checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618"
|
||||
checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
|
||||
dependencies = [
|
||||
"derive_more-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more-impl"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b"
|
||||
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
|
||||
dependencies = [
|
||||
"convert_case 0.10.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
@@ -1005,7 +1005,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1074,7 +1074,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1106,9 +1106,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
|
||||
checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
@@ -1226,7 +1226,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1316,7 +1316,7 @@ dependencies = [
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1356,7 +1356,7 @@ dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1798,9 +1798,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "insta"
|
||||
version = "1.45.0"
|
||||
version = "1.45.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b76866be74d68b1595eb8060cb9191dca9c021db2316558e52ddc5d55d41b66c"
|
||||
checksum = "983e3b24350c84ab8a65151f537d67afbbf7153bb9f1110e03e9fa9b07f67a5c"
|
||||
dependencies = [
|
||||
"console",
|
||||
"once_cell",
|
||||
@@ -1831,9 +1831,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
||||
|
||||
[[package]]
|
||||
name = "iri-string"
|
||||
version = "0.7.9"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397"
|
||||
checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
@@ -1850,9 +1850,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
@@ -1936,7 +1936,7 @@ dependencies = [
|
||||
"http 1.4.0",
|
||||
"proc-macro-error",
|
||||
"server_fn_macro 0.6.15",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1955,7 +1955,7 @@ dependencies = [
|
||||
"leptos_macro",
|
||||
"leptos_meta",
|
||||
"leptos_router",
|
||||
"parking_lot",
|
||||
"or_poisoned",
|
||||
"send_wrapper",
|
||||
"serde_json",
|
||||
"server_fn",
|
||||
@@ -1978,7 +1978,7 @@ dependencies = [
|
||||
"leptos_macro",
|
||||
"leptos_meta",
|
||||
"leptos_router",
|
||||
"parking_lot",
|
||||
"or_poisoned",
|
||||
"server_fn",
|
||||
"tachys",
|
||||
"tokio",
|
||||
@@ -2025,12 +2025,12 @@ dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"indexmap",
|
||||
"parking_lot",
|
||||
"or_poisoned",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rstml",
|
||||
"serde",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
@@ -2070,7 +2070,7 @@ dependencies = [
|
||||
"serde",
|
||||
"server_fn",
|
||||
"server_fn_macro 0.8.8",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
"tracing",
|
||||
"trybuild",
|
||||
"typed-builder",
|
||||
@@ -2125,7 +2125,7 @@ dependencies = [
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2242,7 +2242,7 @@ dependencies = [
|
||||
"manyhow-macros",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2304,13 +2304,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mini-internal"
|
||||
version = "0.1.43"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "560f32b6891d8d9bade8942c45a27694f16d789d3b4b8e6b7135a5240de0a8af"
|
||||
checksum = "2a8df435db5df1dd82a74f77e3c3addf6ab7665079c31e222a64f34f7475d87e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2325,13 +2325,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "miniserde"
|
||||
version = "0.1.43"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac79f4123c070de643a7a93b9339abf18c30005c622bf4b1c29c2c0960f52d39"
|
||||
checksum = "8c48e83ec09ab8a51d4e6be46608bf2a1293a79e2f7ea60246a2ce50eaef44ba"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"mini-internal",
|
||||
"ryu",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2390,7 +2390,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2420,7 +2420,7 @@ version = "0.50.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2493,7 +2493,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2582,7 +2582,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2647,7 +2647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2702,7 +2702,7 @@ dependencies = [
|
||||
"proc-macro-error-attr2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2718,9 +2718,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.103"
|
||||
version = "1.0.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
||||
checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -2733,7 +2733,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
"version_check",
|
||||
"yansi",
|
||||
]
|
||||
@@ -2755,7 +2755,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2841,7 +2841,7 @@ dependencies = [
|
||||
"proc-macro-utils",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2942,7 +2942,7 @@ dependencies = [
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3000,9 +3000,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.26"
|
||||
version = "0.12.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f"
|
||||
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@@ -3084,27 +3084,24 @@ checksum = "bd83f5f173ff41e00337d97f6572e416d022ef8a19f371817259ae960324c482"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmp"
|
||||
version = "0.8.14"
|
||||
version = "0.8.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4"
|
||||
checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"num-traits",
|
||||
"paste",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmp-serde"
|
||||
version = "1.3.0"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db"
|
||||
checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"rmp",
|
||||
"serde",
|
||||
]
|
||||
@@ -3119,7 +3116,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"proc-macro2-diagnostics",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
"syn_derive",
|
||||
"thiserror 2.0.17",
|
||||
]
|
||||
@@ -3147,15 +3144,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.1.2"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
||||
checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3201,9 +3198,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
@@ -3310,7 +3307,7 @@ checksum = "7a1ecb79433fa63a8977c0dd65bfc59bf5f4f195e10a6c5d6d6e198c650cadb1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3341,20 +3338,20 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.145"
|
||||
version = "1.0.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||
checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3381,9 +3378,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392"
|
||||
checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
@@ -3422,7 +3419,7 @@ checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3485,7 +3482,7 @@ dependencies = [
|
||||
"convert_case 0.6.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
"xxhash-rust",
|
||||
]
|
||||
|
||||
@@ -3498,7 +3495,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
"xxhash-rust",
|
||||
]
|
||||
|
||||
@@ -3507,7 +3504,7 @@ name = "server_fn_macro_default"
|
||||
version = "0.8.5"
|
||||
dependencies = [
|
||||
"server_fn_macro 0.8.8",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3540,10 +3537,11 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.7"
|
||||
version = "1.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad"
|
||||
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
||||
dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
]
|
||||
|
||||
@@ -3588,7 +3586,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f62f06db0370222f7f498ef478fce9f8df5828848d1d3517e3331936d7074f55"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3697,9 +3695,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.111"
|
||||
version = "2.0.112"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
|
||||
checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -3715,7 +3713,7 @@ dependencies = [
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3735,7 +3733,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3770,7 +3768,6 @@ dependencies = [
|
||||
"next_tuple",
|
||||
"oco_ref",
|
||||
"or_poisoned",
|
||||
"parking_lot",
|
||||
"paste",
|
||||
"reactive_graph",
|
||||
"reactive_stores",
|
||||
@@ -3814,15 +3811,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.23.0"
|
||||
version = "3.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
|
||||
checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom 0.3.4",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3860,7 +3857,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3871,7 +3868,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3963,7 +3960,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4038,9 +4035,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.9.8"
|
||||
version = "0.9.10+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8"
|
||||
checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
@@ -4053,18 +4050,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.7.3"
|
||||
version = "0.7.5+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533"
|
||||
checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.23.7"
|
||||
version = "0.23.10+spec-1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d"
|
||||
checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
@@ -4163,7 +4160,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4247,7 +4244,7 @@ checksum = "076a02dc54dd46795c2e9c8282ed40bcfb1e22747e955de9389a1de28190fb26"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4389,7 +4386,7 @@ checksum = "59195a1db0e95b920366d949ba5e0d3fc0e70b67c09be15ce5abb790106b0571"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4452,7 +4449,7 @@ dependencies = [
|
||||
"bumpalo",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -4494,7 +4491,7 @@ checksum = "7150335716dce6028bead2b848e72f47b45e7b9422f64cccdc23bedca89affc1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4529,7 +4526,7 @@ dependencies = [
|
||||
"base16",
|
||||
"quote",
|
||||
"sha2",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4567,7 +4564,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4793,7 +4790,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@@ -4814,7 +4811,7 @@ checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4834,7 +4831,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@@ -4874,9 +4871,15 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
"syn 2.0.112",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de9211a9f64b825911bdf0240f58b7a8dac217fe260fc61f080a07f61372fbd5"
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.13.3"
|
||||
|
||||
16
Cargo.toml
16
Cargo.toml
@@ -74,7 +74,7 @@ tachys = { path = "./tachys", version = "0.2.11" }
|
||||
async-once-cell = { default-features = false, version = "0.5.4" }
|
||||
itertools = { default-features = false, version = "0.14.0" }
|
||||
convert_case = { default-features = false, version = "0.10.0" }
|
||||
serde_json = { default-features = false, version = "1.0.145" }
|
||||
serde_json = { default-features = false, version = "1.0.148" }
|
||||
trybuild = { default-features = false, version = "1.0.114" }
|
||||
typed-builder = { default-features = false, version = "0.23.2" }
|
||||
typed-builder-macro = { default-features = false, version = "0.23.2" }
|
||||
@@ -103,10 +103,10 @@ base64 = { default-features = false, version = "0.22.1" }
|
||||
cfg-if = { default-features = false, version = "1.0.4" }
|
||||
wasm-bindgen-futures = { default-features = false, version = "0.4.56" }
|
||||
tower = { default-features = false, version = "0.5.2" }
|
||||
proc-macro2 = { default-features = false, version = "1.0.103" }
|
||||
proc-macro2 = { default-features = false, version = "1.0.104" }
|
||||
serde = { default-features = false, version = "1.0.228" }
|
||||
parking_lot = { default-features = false, version = "0.12.5" }
|
||||
axum = { default-features = false, version = "0.8.7" }
|
||||
axum = { default-features = false, version = "0.8.8" }
|
||||
serde_qs = { default-features = false, version = "0.15.0" }
|
||||
syn = { default-features = false, version = "2.0.111" }
|
||||
xxhash-rust = { default-features = false, version = "0.8.15" }
|
||||
@@ -144,7 +144,7 @@ bytes = { default-features = false, version = "1.11.0" }
|
||||
http = { default-features = false, version = "1.4.0" }
|
||||
regex = { default-features = false, version = "1.12.2" }
|
||||
drain_filter_polyfill = { default-features = false, version = "0.1.3" }
|
||||
tempfile = { default-features = false, version = "3.23.0" }
|
||||
tempfile = { default-features = false, version = "3.24.0" }
|
||||
futures-lite = { default-features = false, version = "2.6.1" }
|
||||
log = { default-features = false, version = "0.4.29" }
|
||||
percent-encoding = { default-features = false, version = "2.3.2" }
|
||||
@@ -153,18 +153,18 @@ const-str = { default-features = false, version = "0.7.1" }
|
||||
http-body-util = { default-features = false, version = "0.1.3" }
|
||||
hyper = { default-features = false, version = "1.8.1" }
|
||||
postcard = { default-features = false, version = "1.1.3" }
|
||||
rmp-serde = { default-features = false, version = "1.3.0" }
|
||||
reqwest = { default-features = false, version = "0.12.26" }
|
||||
rmp-serde = { default-features = false, version = "1.3.1" }
|
||||
reqwest = { default-features = false, version = "0.12.28" }
|
||||
tower-layer = { default-features = false, version = "0.3.3" }
|
||||
attribute-derive = { default-features = false, version = "0.10.5" }
|
||||
insta = { default-features = false, version = "1.45.0" }
|
||||
insta = { default-features = false, version = "1.45.1" }
|
||||
codee = { default-features = false, version = "0.3.5" }
|
||||
actix-http = { default-features = false, version = "3.11.2" }
|
||||
wasm-bindgen-test = { default-features = false, version = "0.3.56" }
|
||||
rustversion = { default-features = false, version = "1.0.22" }
|
||||
getrandom = { default-features = false, version = "0.3.4" }
|
||||
actix-files = { default-features = false, version = "0.6.9" }
|
||||
async-lock = { default-features = false, version = "3.4.1" }
|
||||
async-lock = { default-features = false, version = "3.4.2" }
|
||||
base16 = { default-features = false, version = "0.2.1" }
|
||||
digest = { default-features = false, version = "0.10.7" }
|
||||
sha2 = { default-features = false, version = "0.10.9" }
|
||||
|
||||
@@ -74,8 +74,8 @@ Leptos is a full-stack, isomorphic Rust web framework leveraging fine-grained re
|
||||
|
||||
## What does that mean?
|
||||
|
||||
- **Full-stack**: Leptos can be used to build apps that run in the browser (client-side rendering), on the server (server-side rendering), or by rendering HTML on the server and then adding interactivity in the browser (server-side rendering with hydration). This includes support for HTTP streaming of both data ([`Resource`s](https://docs.rs/leptos/latest/leptos/struct.Resource.html)) and HTML (out-of-order or in-order streaming of [`<Suspense/>`](https://docs.rs/leptos/latest/leptos/fn.Suspense.html) components.)
|
||||
- **Isomorphic**: Leptos provides primitives to write isomorphic [server functions](https://docs.rs/leptos_server/0.2.5/leptos_server/index.html), i.e., functions that can be called with the “same shape” on the client or server, but only run on the server. This means you can write your server-only logic (database requests, authentication etc.) alongside the client-side components that will consume it, and call server functions as if they were running in the browser, without needing to create and maintain a separate REST or other API.
|
||||
- **Full-stack**: Leptos can be used to build apps that run in the browser (client-side rendering), on the server (server-side rendering), or by rendering HTML on the server and then adding interactivity in the browser (server-side rendering with hydration). This includes support for HTTP streaming of both data ([`Resource`s](https://docs.rs/leptos/latest/leptos/prelude/struct.Resource.html)) and HTML (out-of-order or in-order streaming of [`<Suspense/>`](https://docs.rs/leptos/latest/leptos/suspense/fn.Suspense.html) components.)
|
||||
- **Isomorphic**: Leptos provides primitives to write isomorphic [server functions](https://docs.rs/server_fn/latest/server_fn/), i.e., functions that can be called with the “same shape” on the client or server, but only run on the server. This means you can write your server-only logic (database requests, authentication etc.) alongside the client-side components that will consume it, and call server functions as if they were running in the browser, without needing to create and maintain a separate REST or other API.
|
||||
- **Web**: Leptos is built on the Web platform and Web standards. The [router](https://docs.rs/leptos_router/latest/leptos_router/) is designed to use Web fundamentals (like links and forms) and build on top of them rather than trying to replace them.
|
||||
- **Framework**: Leptos provides most of what you need to build a modern web app: a reactive system, templating library, and a router that works on both the server and client side.
|
||||
- **Fine-grained reactivity**: The entire framework is built from reactive primitives. This allows for extremely performant code with minimal overhead: when a reactive signal’s value changes, it can update a single text node, toggle a single class, or remove an element from the DOM without any other code running. (So, no virtual DOM overhead!)
|
||||
|
||||
@@ -9,12 +9,12 @@ This document is intended as a running list of common issues, with example code
|
||||
**Issue**: Sometimes you want to update a reactive signal in a way that depends on another signal.
|
||||
|
||||
```rust
|
||||
let (a, set_a) = create_signal(0);
|
||||
let (b, set_b) = create_signal(false);
|
||||
let (a, set_a) = signal(0);
|
||||
let (b, set_b) = signal(false);
|
||||
|
||||
create_effect(move |_| {
|
||||
if a() > 5 {
|
||||
set_b(true);
|
||||
Effect::new(move |_| {
|
||||
if a.get() > 5 {
|
||||
set_b.set(true);
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -24,56 +24,10 @@ This creates an inefficient chain of updates, and can easily lead to infinite lo
|
||||
**Solution**: Follow the rule, _What can be derived, should be derived._ In this case, this has the benefit of massively reducing the code size, too!
|
||||
|
||||
```rust
|
||||
let (a, set_a) = create_signal(0);
|
||||
let b = move || a () > 5;
|
||||
let (a, set_a) = signal(0);
|
||||
let b = move || a.get() > 5;
|
||||
```
|
||||
|
||||
### Nested signal updates/reads triggering panic
|
||||
|
||||
Sometimes you have nested signals: for example, hash-map that can change over time, each of whose values can also change over time:
|
||||
|
||||
```rust
|
||||
#[component]
|
||||
pub fn App() -> impl IntoView {
|
||||
let resources = create_rw_signal(HashMap::new());
|
||||
|
||||
let update = move |id: usize| {
|
||||
resources.update(|resources| {
|
||||
resources
|
||||
.entry(id)
|
||||
.or_insert_with(|| create_rw_signal(0))
|
||||
.update(|amount| *amount += 1)
|
||||
})
|
||||
};
|
||||
|
||||
view! {
|
||||
<div>
|
||||
<pre>{move || format!("{:#?}", resources.get().into_iter().map(|(id, resource)| (id, resource.get())).collect::<Vec<_>>())}</pre>
|
||||
<button on:click=move |_| update(1)>"+"</button>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Clicking the button twice will cause a panic, because of the nested signal _read_. Calling the `update` function on `resources` immediately takes out a mutable borrow on `resources`, then updates the `resource` signal—which re-runs the effect that reads from the signals, which tries to immutably access `resources` and panics. It's the nested update here which causes a problem, because the inner update triggers and effect that tries to read both signals while the outer is still updating.
|
||||
|
||||
You can fix this fairly easily by using the [`batch()`](https://docs.rs/leptos/latest/leptos/fn.batch.html) method:
|
||||
|
||||
```rust
|
||||
let update = move |id: usize| {
|
||||
batch(move || {
|
||||
resources.update(|resources| {
|
||||
resources
|
||||
.entry(id)
|
||||
.or_insert_with(|| create_rw_signal(0))
|
||||
.update(|amount| *amount += 1)
|
||||
})
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
This delays running any effects until after both updates are made, preventing the conflict entirely without requiring any other restructuring.
|
||||
|
||||
## Templates and the DOM
|
||||
|
||||
### `<input value=...>` doesn't update or stops updating
|
||||
@@ -83,8 +37,8 @@ Many DOM attributes can be updated either by setting an attribute on the DOM nod
|
||||
This means that in practice, attributes like `value` or `checked` on an `<input/>` element only update the _default_ value for the `<input/>`. If you want to reactively update the value, you should use `prop:value` instead to set the `value` property.
|
||||
|
||||
```rust
|
||||
let (a, set_a) = create_signal("Starting value".to_string());
|
||||
let on_input = move |ev| set_a(event_target_value(&ev));
|
||||
let (a, set_a) = signal("Starting value".to_string());
|
||||
let on_input = move |ev| set_a.set(event_target_value(&ev));
|
||||
|
||||
view! {
|
||||
|
||||
@@ -97,8 +51,8 @@ view! {
|
||||
```
|
||||
|
||||
```rust
|
||||
let (a, set_a) = create_signal("Starting value".to_string());
|
||||
let on_input = move |ev| set_a(event_target_value(&ev));
|
||||
let (a, set_a) = signal("Starting value".to_string());
|
||||
let on_input = move |ev| set_a.set(event_target_value(&ev));
|
||||
|
||||
view! {
|
||||
|
||||
|
||||
@@ -23,11 +23,11 @@ leptos_router = { workspace = true, features = ["ssr"] }
|
||||
server_fn = { workspace = true, features = ["actix-no-default"] }
|
||||
tachys = { workspace = true }
|
||||
serde_json = { workspace = true, default-features = true }
|
||||
parking_lot = { workspace = true, default-features = true }
|
||||
tracing = { optional = true, workspace = true, default-features = true }
|
||||
tokio = { features = ["rt", "fs"], workspace = true, default-features = true }
|
||||
send_wrapper = { workspace = true, default-features = true }
|
||||
dashmap = { workspace = true, default-features = true }
|
||||
or_poisoned = { workspace = true, default-features = true }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
rustdoc-args = ["--generate-link-to-definition"]
|
||||
|
||||
@@ -38,7 +38,7 @@ use leptos_router::{
|
||||
static_routes::{RegenerationFn, ResolvedStaticPath},
|
||||
ExpandOptionals, Method, PathSegment, RouteList, RouteListing, SsrMode,
|
||||
};
|
||||
use parking_lot::RwLock;
|
||||
use or_poisoned::OrPoisoned;
|
||||
use send_wrapper::SendWrapper;
|
||||
use server_fn::{
|
||||
error::ServerFnErrorErr, redirect::REDIRECT_HEADER,
|
||||
@@ -50,7 +50,7 @@ use std::{
|
||||
future::Future,
|
||||
ops::{Deref, DerefMut},
|
||||
path::Path,
|
||||
sync::{Arc, LazyLock},
|
||||
sync::{Arc, LazyLock, RwLock},
|
||||
};
|
||||
|
||||
/// This struct lets you define headers and override the status of the Response from an Element or a Server Function
|
||||
@@ -121,12 +121,12 @@ pub struct ResponseOptions(pub Arc<RwLock<ResponseParts>>);
|
||||
impl ResponseOptions {
|
||||
/// A simpler way to overwrite the contents of `ResponseOptions` with a new `ResponseParts`.
|
||||
pub fn overwrite(&self, parts: ResponseParts) {
|
||||
let mut writable = self.0.write();
|
||||
let mut writable = self.0.write().or_poisoned();
|
||||
*writable = parts
|
||||
}
|
||||
/// Set the status of the returned Response.
|
||||
pub fn set_status(&self, status: StatusCode) {
|
||||
let mut writeable = self.0.write();
|
||||
let mut writeable = self.0.write().or_poisoned();
|
||||
let res_parts = &mut *writeable;
|
||||
res_parts.status = Some(status);
|
||||
}
|
||||
@@ -136,7 +136,7 @@ impl ResponseOptions {
|
||||
key: header::HeaderName,
|
||||
value: header::HeaderValue,
|
||||
) {
|
||||
let mut writeable = self.0.write();
|
||||
let mut writeable = self.0.write().or_poisoned();
|
||||
let res_parts = &mut *writeable;
|
||||
res_parts.headers.insert(key, value);
|
||||
}
|
||||
@@ -146,7 +146,7 @@ impl ResponseOptions {
|
||||
key: header::HeaderName,
|
||||
value: header::HeaderValue,
|
||||
) {
|
||||
let mut writeable = self.0.write();
|
||||
let mut writeable = self.0.write().or_poisoned();
|
||||
let res_parts = &mut *writeable;
|
||||
res_parts.headers.append(key, value);
|
||||
}
|
||||
@@ -170,7 +170,7 @@ impl ExtendResponse for ActixResponse {
|
||||
}
|
||||
|
||||
fn extend_response(&mut self, res_options: &Self::ResponseOptions) {
|
||||
let mut res_options = res_options.0.write();
|
||||
let mut res_options = res_options.0.write().or_poisoned();
|
||||
|
||||
let headers = self.0.headers_mut();
|
||||
for (key, value) in std::mem::take(&mut res_options.headers) {
|
||||
@@ -394,7 +394,8 @@ pub fn handle_server_fns_with_context(
|
||||
// the Location header may have been set to Referer, so any redirection by the
|
||||
// user must overwrite it
|
||||
{
|
||||
let mut res_options = res_options.0.write();
|
||||
let mut res_options =
|
||||
res_options.0.write().or_poisoned();
|
||||
let headers = res.0.headers_mut();
|
||||
|
||||
for location in
|
||||
@@ -1227,7 +1228,7 @@ static STATIC_HEADERS: LazyLock<DashMap<String, ResponseOptions>> =
|
||||
|
||||
fn was_404(owner: &Owner) -> bool {
|
||||
let resp = owner.with(|| expect_context::<ResponseOptions>());
|
||||
let status = resp.0.read().status;
|
||||
let status = resp.0.read().or_poisoned().status;
|
||||
|
||||
if let Some(status) = status {
|
||||
return status == StatusCode::NOT_FOUND;
|
||||
|
||||
@@ -23,11 +23,11 @@ leptos_meta = { workspace = true, features = ["ssr", "nonce"] }
|
||||
leptos_router = { workspace = true, features = ["ssr"] }
|
||||
leptos_integration_utils = { workspace = true }
|
||||
tachys = { workspace = true }
|
||||
parking_lot = { workspace = true, default-features = true }
|
||||
tokio = { default-features = false, workspace = true }
|
||||
tower = { features = ["util"], workspace = true, default-features = true }
|
||||
tower-http = { workspace = true, default-features = true }
|
||||
tracing = { optional = true, workspace = true, default-features = true }
|
||||
or_poisoned = { workspace = true, default-features = true }
|
||||
|
||||
[dev-dependencies]
|
||||
axum = { workspace = true, default-features = true }
|
||||
|
||||
@@ -69,13 +69,19 @@ use leptos_router::{
|
||||
static_routes::RegenerationFn, ExpandOptionals, PathSegment, RouteList,
|
||||
RouteListing, SsrMode,
|
||||
};
|
||||
use parking_lot::RwLock;
|
||||
use or_poisoned::OrPoisoned;
|
||||
use server_fn::{error::ServerFnErrorErr, redirect::REDIRECT_HEADER};
|
||||
#[cfg(feature = "default")]
|
||||
use std::path::Path;
|
||||
#[cfg(feature = "default")]
|
||||
use std::sync::LazyLock;
|
||||
use std::{collections::HashSet, fmt::Debug, io, pin::Pin, sync::Arc};
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
fmt::Debug,
|
||||
io,
|
||||
pin::Pin,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
#[cfg(feature = "default")]
|
||||
use tower::util::ServiceExt;
|
||||
#[cfg(feature = "default")]
|
||||
@@ -126,24 +132,24 @@ pub struct ResponseOptions(pub Arc<RwLock<ResponseParts>>);
|
||||
impl ResponseOptions {
|
||||
/// A simpler way to overwrite the contents of `ResponseOptions` with a new `ResponseParts`.
|
||||
pub fn overwrite(&self, parts: ResponseParts) {
|
||||
let mut writable = self.0.write();
|
||||
let mut writable = self.0.write().or_poisoned();
|
||||
*writable = parts
|
||||
}
|
||||
/// Set the status of the returned Response.
|
||||
pub fn set_status(&self, status: StatusCode) {
|
||||
let mut writeable = self.0.write();
|
||||
let mut writeable = self.0.write().or_poisoned();
|
||||
let res_parts = &mut *writeable;
|
||||
res_parts.status = Some(status);
|
||||
}
|
||||
/// Insert a header, overwriting any previous value with the same key.
|
||||
pub fn insert_header(&self, key: HeaderName, value: HeaderValue) {
|
||||
let mut writeable = self.0.write();
|
||||
let mut writeable = self.0.write().or_poisoned();
|
||||
let res_parts = &mut *writeable;
|
||||
res_parts.headers.insert(key, value);
|
||||
}
|
||||
/// Append a header, leaving any header with the same key intact.
|
||||
pub fn append_header(&self, key: HeaderName, value: HeaderValue) {
|
||||
let mut writeable = self.0.write();
|
||||
let mut writeable = self.0.write().or_poisoned();
|
||||
let res_parts = &mut *writeable;
|
||||
res_parts.headers.append(key, value);
|
||||
}
|
||||
@@ -166,7 +172,7 @@ impl ExtendResponse for AxumResponse {
|
||||
}
|
||||
|
||||
fn extend_response(&mut self, res_options: &Self::ResponseOptions) {
|
||||
let mut res_options = res_options.0.write();
|
||||
let mut res_options = res_options.0.write().or_poisoned();
|
||||
if let Some(status) = res_options.status {
|
||||
*self.0.status_mut() = status;
|
||||
}
|
||||
@@ -1528,7 +1534,7 @@ static STATIC_HEADERS: LazyLock<DashMap<String, ResponseOptions>> =
|
||||
#[cfg(feature = "default")]
|
||||
fn was_404(owner: &Owner) -> bool {
|
||||
let resp = owner.with(|| expect_context::<ResponseOptions>());
|
||||
let status = resp.0.read().status;
|
||||
let status = resp.0.read().or_poisoned().status;
|
||||
|
||||
if let Some(status) = status {
|
||||
return status == StatusCode::NOT_FOUND;
|
||||
|
||||
@@ -1,25 +1,42 @@
|
||||
if (window.location.protocol === 'https:') {
|
||||
protocol = 'wss://';
|
||||
if (window.location.protocol === "https:") {
|
||||
protocol = "wss://";
|
||||
}
|
||||
|
||||
let host = window.location.hostname;
|
||||
let ws = new WebSocket(`${protocol}${host}:${reload_port}/live_reload`);
|
||||
ws.onmessage = (ev) => {
|
||||
let msg = JSON.parse(ev.data);
|
||||
if (msg.all) window.location.reload();
|
||||
if (msg.css) {
|
||||
let found = false;
|
||||
document.querySelectorAll("link").forEach((link) => {
|
||||
if (link.getAttribute('href').includes(msg.css)) {
|
||||
let newHref = '/' + msg.css + '?version=' + Date.now();
|
||||
link.setAttribute('href', newHref);
|
||||
found = true;
|
||||
}
|
||||
});
|
||||
if (!found) console.warn(`CSS hot-reload: Could not find a <link href=/\"${msg.css}\"> element`);
|
||||
|
||||
function connect() {
|
||||
let ws = new WebSocket(`${protocol}${host}:${reload_port}/live_reload`);
|
||||
|
||||
ws.onmessage = (ev) => {
|
||||
let msg = JSON.parse(ev.data);
|
||||
if (msg.all) window.location.reload();
|
||||
if (msg.css) {
|
||||
let found = false;
|
||||
document.querySelectorAll("link").forEach((link) => {
|
||||
if (link.getAttribute("href").includes(msg.css)) {
|
||||
let newHref = "/" + msg.css + "?version=" + Date.now();
|
||||
link.setAttribute("href", newHref);
|
||||
found = true;
|
||||
}
|
||||
});
|
||||
if (!found)
|
||||
console.warn(
|
||||
`CSS hot-reload: Could not find a <link href=/\"${msg.css}\"> element`,
|
||||
);
|
||||
}
|
||||
if (msg.view) {
|
||||
patch(msg.view);
|
||||
}
|
||||
};
|
||||
if(msg.view) {
|
||||
patch(msg.view);
|
||||
}
|
||||
};
|
||||
ws.onclose = () => console.warn('Live-reload stopped. Manual reload necessary.');
|
||||
|
||||
ws.onclose = () => {
|
||||
console.warn("Live-reload disconnected. Reconnecting...");
|
||||
setTimeout(connect, 1000);
|
||||
};
|
||||
|
||||
ws.onerror = () => {
|
||||
ws.close();
|
||||
};
|
||||
}
|
||||
|
||||
connect();
|
||||
|
||||
@@ -25,7 +25,7 @@ proc-macro2 = { features = [
|
||||
"span-locations",
|
||||
"nightly",
|
||||
], workspace = true, default-features = true }
|
||||
parking_lot = { workspace = true, default-features = true }
|
||||
walkdir = { workspace = true, default-features = true }
|
||||
camino = { workspace = true, default-features = true }
|
||||
indexmap = { workspace = true, default-features = true }
|
||||
or_poisoned = { workspace = true, default-features = true }
|
||||
|
||||
@@ -4,14 +4,14 @@ use anyhow::Result;
|
||||
use camino::Utf8PathBuf;
|
||||
use diff::Patches;
|
||||
use node::LNode;
|
||||
use parking_lot::RwLock;
|
||||
use or_poisoned::OrPoisoned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs::File,
|
||||
io::Read,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use syn::{
|
||||
spanned::Spanned,
|
||||
@@ -58,7 +58,7 @@ impl ViewMacros {
|
||||
}
|
||||
}
|
||||
|
||||
*self.views.write() = views;
|
||||
*self.views.write().or_poisoned() = views;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -101,7 +101,7 @@ impl ViewMacros {
|
||||
/// Will return `Err` if the contents of the file cannot be parsed.
|
||||
pub fn patch(&self, path: &Utf8PathBuf) -> Result<Option<Patches>> {
|
||||
let new_views = Self::parse_file(path)?;
|
||||
let mut lock = self.views.write();
|
||||
let mut lock = self.views.write().or_poisoned();
|
||||
let diffs = match lock.get(path) {
|
||||
None => return Ok(None),
|
||||
Some(current_views) => {
|
||||
|
||||
@@ -199,7 +199,7 @@ mod slot;
|
||||
/// ```
|
||||
///
|
||||
/// 9. You can use the `node_ref` or `_ref` attribute to store a reference to its DOM element in a
|
||||
/// [NodeRef](https://docs.rs/leptos/latest/leptos/struct.NodeRef.html) to use later.
|
||||
/// [NodeRef](https://docs.rs/leptos/latest/leptos/prelude/struct.NodeRef.html) to use later.
|
||||
/// ```rust
|
||||
/// # use leptos::prelude::*;
|
||||
///
|
||||
@@ -505,9 +505,9 @@ pub fn include_view(tokens: TokenStream) -> TokenStream {
|
||||
///
|
||||
/// * `#[prop(into)]`: This will call `.into()` on any value passed into the component prop. (For example,
|
||||
/// you could apply `#[prop(into)]` to a prop that takes
|
||||
/// [Signal](https://docs.rs/leptos/latest/leptos/struct.Signal.html), which would
|
||||
/// allow users to pass a [ReadSignal](https://docs.rs/leptos/latest/leptos/struct.ReadSignal.html) or
|
||||
/// [RwSignal](https://docs.rs/leptos/latest/leptos/struct.RwSignal.html)
|
||||
/// [Signal](https://docs.rs/leptos/latest/leptos/prelude/struct.Signal.html), which would
|
||||
/// allow users to pass a [ReadSignal](https://docs.rs/leptos/latest/leptos/prelude/struct.ReadSignal.html) or
|
||||
/// [RwSignal](https://docs.rs/leptos/latest/leptos/prelude/struct.RwSignal.html)
|
||||
/// and automatically convert it.)
|
||||
/// * `#[prop(optional)]`: If the user does not specify this property when they use the component,
|
||||
/// it will be set to its default value. If the property type is `Option<T>`, values should be passed
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn params_impl(ast: &syn::DeriveInput) -> proc_macro::TokenStream {
|
||||
let span = field.span();
|
||||
|
||||
quote_spanned! {
|
||||
span=> #ident: <#ty as ::leptos_router::params::IntoParam>::into_param(
|
||||
span=> #ident: ::leptos_router::params::macro_helpers::Wrapper::<#ty>::__into_param(
|
||||
map.get_str(#field_name_string),
|
||||
#field_name_string
|
||||
)?
|
||||
@@ -39,6 +39,8 @@ pub fn params_impl(ast: &syn::DeriveInput) -> proc_macro::TokenStream {
|
||||
let gen = quote! {
|
||||
impl Params for #name {
|
||||
fn from_map(map: &::leptos_router::params::ParamsMap) -> ::core::result::Result<Self, ::leptos_router::params::ParamsError> {
|
||||
use ::leptos_router::params::macro_helpers::Fallback as _;
|
||||
|
||||
Ok(Self {
|
||||
#(#fields,)*
|
||||
})
|
||||
|
||||
@@ -140,13 +140,20 @@ where
|
||||
}
|
||||
|
||||
fn track_field(&self) {
|
||||
let inner = self
|
||||
.inner
|
||||
.get_trigger(self.inner.path().into_iter().collect());
|
||||
inner.this.track();
|
||||
let mut full_path = self.path().into_iter().collect::<StorePath>();
|
||||
let trigger = self.get_trigger(self.path().into_iter().collect());
|
||||
trigger.this.track();
|
||||
trigger.children.track();
|
||||
|
||||
// tracks `this` for all ancestors: i.e., it will track any change that is made
|
||||
// directly to one of its ancestors, but not a change made to a *child* of an ancestor
|
||||
// (which would end up with every subfield tracking its own siblings, because they are
|
||||
// children of its parent)
|
||||
while !full_path.is_empty() {
|
||||
full_path.pop();
|
||||
let inner = self.get_trigger(full_path.clone());
|
||||
inner.this.track();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,11 +57,11 @@
|
||||
//! # if false { // don't run effect in doctests
|
||||
//! Effect::new(move |_| {
|
||||
//! // you can access individual store fields with a getter
|
||||
//! println!("todos: {:?}", &*store.todos().read());
|
||||
//! println!("user: {:?}", &*store.user().read());
|
||||
//! });
|
||||
//! # }
|
||||
//!
|
||||
//! // won't notify the effect that listens to `todos`
|
||||
//! // won't notify the effect that listens to `user`
|
||||
//! store.todos().write().push(Todo {
|
||||
//! label: "Test".to_string(),
|
||||
//! completed: false,
|
||||
|
||||
@@ -199,31 +199,56 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// TODO can we support Option<T> and T in a non-nightly way?
|
||||
#[cfg(all(feature = "nightly", rustc_nightly))]
|
||||
mod option_param {
|
||||
use super::{IntoParam, ParamsError};
|
||||
/// Helpers for the `Params` derive macro to allow specialization without nightly.
|
||||
pub mod macro_helpers {
|
||||
use crate::params::{IntoParam, ParamsError};
|
||||
use std::{str::FromStr, sync::Arc};
|
||||
|
||||
auto trait NotOption {}
|
||||
impl<T> !NotOption for Option<T> {}
|
||||
/// This struct is never actually created; it just exists so that we can impl associated
|
||||
/// functions on it.
|
||||
pub struct Wrapper<T>(T);
|
||||
|
||||
impl<T> IntoParam for T
|
||||
where
|
||||
T: FromStr + NotOption,
|
||||
<T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
|
||||
{
|
||||
fn into_param(
|
||||
impl<T: IntoParam> Wrapper<T> {
|
||||
/// This is the 'preferred' impl to be used for all `T` that implement `IntoParam`.
|
||||
/// Because it is directly on the struct, the compiler will pick this over the impl from
|
||||
/// the `Fallback` trait.
|
||||
#[inline]
|
||||
pub fn __into_param(
|
||||
value: Option<&str>,
|
||||
name: &str,
|
||||
) -> Result<Self, ParamsError> {
|
||||
let value = value
|
||||
.ok_or_else(|| ParamsError::MissingParam(name.to_string()))?;
|
||||
Self::from_str(value).map_err(|e| ParamsError::Params(Arc::new(e)))
|
||||
) -> Result<T, ParamsError> {
|
||||
T::into_param(value, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// If the Fallback trait is in scope, then the compiler has two possible implementations for
|
||||
/// `__into_params`. It will pick the one from this trait if the inherent one doesn't exist.
|
||||
/// (which it won't if `T` does not implement `IntoParam`)
|
||||
pub trait Fallback<T>: Sized
|
||||
where
|
||||
T: FromStr,
|
||||
<T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
|
||||
{
|
||||
/// Fallback function in case the inherent impl on the Wrapper struct does not exist for
|
||||
/// `T`
|
||||
#[inline]
|
||||
fn __into_param(
|
||||
value: Option<&str>,
|
||||
name: &str,
|
||||
) -> Result<T, ParamsError> {
|
||||
let value = value
|
||||
.ok_or_else(|| ParamsError::MissingParam(name.to_string()))?;
|
||||
T::from_str(value).map_err(|e| ParamsError::Params(Arc::new(e)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Fallback<T> for Wrapper<T>
|
||||
where
|
||||
T: FromStr,
|
||||
<T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
|
||||
{
|
||||
}
|
||||
}
|
||||
/// Errors that can occur while parsing params using [`Params`].
|
||||
#[derive(Error, Debug, Clone)]
|
||||
pub enum ParamsError {
|
||||
|
||||
@@ -309,6 +309,16 @@ impl ServerFnCall {
|
||||
.collect::<TokenStream2>()
|
||||
}
|
||||
|
||||
/// Get the lint attributes for the server function.
|
||||
pub fn lint_attrs(&self) -> TokenStream2 {
|
||||
// pass through lint attributes from the function body
|
||||
self.body
|
||||
.lint_attrs
|
||||
.iter()
|
||||
.map(|lint_attr| quote!(#lint_attr))
|
||||
.collect::<TokenStream2>()
|
||||
}
|
||||
|
||||
fn fn_name_as_str(&self) -> String {
|
||||
self.body.ident.to_string()
|
||||
}
|
||||
@@ -388,6 +398,8 @@ impl ServerFnCall {
|
||||
PathInfo::None => quote! {},
|
||||
};
|
||||
|
||||
let lint_attrs = self.lint_attrs();
|
||||
|
||||
let vis = &self.body.vis;
|
||||
let struct_name = self.struct_name();
|
||||
let fields = self
|
||||
@@ -410,6 +422,7 @@ impl ServerFnCall {
|
||||
#docs
|
||||
#[derive(Debug, #derives)]
|
||||
#addl_path
|
||||
#lint_attrs
|
||||
#vis struct #struct_name {
|
||||
#(#fields),*
|
||||
}
|
||||
@@ -1465,6 +1478,8 @@ pub struct ServerFnBody {
|
||||
pub block: TokenStream2,
|
||||
/// The documentation of the server function.
|
||||
pub docs: Vec<(String, Span)>,
|
||||
/// The lint attributes of the server function.
|
||||
pub lint_attrs: Vec<Attribute>,
|
||||
/// The middleware attributes applied to the server function.
|
||||
pub middlewares: Vec<Middleware>,
|
||||
}
|
||||
@@ -1522,6 +1537,27 @@ impl Parse for ServerFnBody {
|
||||
};
|
||||
!attr.path.is_ident("doc")
|
||||
});
|
||||
|
||||
let lint_attrs = attrs
|
||||
.iter()
|
||||
.filter_map(|attr| {
|
||||
if attr.path().is_ident("allow")
|
||||
|| attr.path().is_ident("warn")
|
||||
|| attr.path().is_ident("deny")
|
||||
|| attr.path().is_ident("forbid")
|
||||
{
|
||||
return Some(attr.clone());
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect();
|
||||
attrs.retain(|attr| {
|
||||
!attr.path().is_ident("allow")
|
||||
&& !attr.path().is_ident("warn")
|
||||
&& !attr.path().is_ident("deny")
|
||||
&& !attr.path().is_ident("forbid")
|
||||
});
|
||||
|
||||
// extract all #[middleware] attributes, removing them from signature of dummy
|
||||
let mut middlewares: Vec<Middleware> = vec![];
|
||||
attrs.retain(|attr| {
|
||||
@@ -1557,6 +1593,7 @@ impl Parse for ServerFnBody {
|
||||
block,
|
||||
attrs,
|
||||
docs,
|
||||
lint_attrs,
|
||||
middlewares,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -152,7 +152,6 @@ drain_filter_polyfill = { workspace = true, default-features = true }
|
||||
indexmap = { workspace = true, default-features = true }
|
||||
rustc-hash = { workspace = true, default-features = true }
|
||||
futures = { workspace = true, default-features = true }
|
||||
parking_lot = { workspace = true, default-features = true }
|
||||
itertools = { workspace = true, default-features = true }
|
||||
send_wrapper = { workspace = true, default-features = true }
|
||||
linear-map = { workspace = true, default-features = true }
|
||||
|
||||
@@ -23,14 +23,32 @@ pub fn keyed<T, I, K, KF, VF, VFS, V>(
|
||||
) -> Keyed<T, I, K, KF, VF, VFS, V>
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
K: Eq + Hash + 'static,
|
||||
K: Eq + Hash + SerializableKey + 'static,
|
||||
KF: Fn(&T) -> K,
|
||||
V: Render,
|
||||
VF: Fn(usize, T) -> (VFS, V),
|
||||
VFS: Fn(usize),
|
||||
{
|
||||
Keyed {
|
||||
items,
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
items: Some(items),
|
||||
#[cfg(feature = "ssr")]
|
||||
items: None,
|
||||
#[cfg(feature = "ssr")]
|
||||
ssr_items: items
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, t)| {
|
||||
let key = if cfg!(feature = "islands") {
|
||||
let key = (key_fn)(&t);
|
||||
key.ser_key()
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let (_, view) = (view_fn)(i, t);
|
||||
(key, view)
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
key_fn,
|
||||
view_fn,
|
||||
}
|
||||
@@ -45,7 +63,9 @@ where
|
||||
VF: Fn(usize, T) -> (VFS, V),
|
||||
VFS: Fn(usize),
|
||||
{
|
||||
items: I,
|
||||
items: Option<I>,
|
||||
#[cfg(feature = "ssr")]
|
||||
ssr_items: Vec<(String, V)>,
|
||||
key_fn: KF,
|
||||
view_fn: VF,
|
||||
}
|
||||
@@ -106,14 +126,13 @@ where
|
||||
VFS: Fn(usize),
|
||||
{
|
||||
type State = KeyedState<K, VFS, V>;
|
||||
// TODO fallible state and try_build()/try_rebuild() here
|
||||
|
||||
fn build(self) -> Self::State {
|
||||
let items = self.items.into_iter();
|
||||
let items = self.items.into_iter().flatten();
|
||||
let (capacity, _) = items.size_hint();
|
||||
let mut hashed_items =
|
||||
FxIndexSet::with_capacity_and_hasher(capacity, Default::default());
|
||||
let mut rendered_items = Vec::new();
|
||||
let mut rendered_items = Vec::with_capacity(capacity);
|
||||
for (index, item) in items.enumerate() {
|
||||
hashed_items.insert((self.key_fn)(&item));
|
||||
let (set_index, view) = (self.view_fn)(index, item);
|
||||
@@ -134,7 +153,7 @@ where
|
||||
hashed_items,
|
||||
ref mut rendered_items,
|
||||
} = state;
|
||||
let new_items = self.items.into_iter();
|
||||
let new_items = self.items.into_iter().flatten();
|
||||
let (capacity, _) = new_items.size_hint();
|
||||
let mut new_hashed_items =
|
||||
FxIndexSet::with_capacity_and_hasher(capacity, Default::default());
|
||||
@@ -198,6 +217,8 @@ where
|
||||
{
|
||||
let Keyed {
|
||||
items,
|
||||
#[cfg(feature = "ssr")]
|
||||
ssr_items,
|
||||
key_fn,
|
||||
view_fn,
|
||||
} = self;
|
||||
@@ -205,6 +226,11 @@ where
|
||||
Keyed {
|
||||
items,
|
||||
key_fn,
|
||||
#[cfg(feature = "ssr")]
|
||||
ssr_items: ssr_items
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, v.add_any_attr(attr.clone())))
|
||||
.collect(),
|
||||
view_fn: Box::new(move |index, item| {
|
||||
let (index, view) = view_fn(index, item);
|
||||
(index, view.add_any_attr(attr.clone()))
|
||||
@@ -229,21 +255,39 @@ where
|
||||
const MIN_LENGTH: usize = 0;
|
||||
|
||||
fn dry_resolve(&mut self) {
|
||||
// TODO...
|
||||
#[cfg(feature = "ssr")]
|
||||
for view in &mut self.ssr_items {
|
||||
view.dry_resolve();
|
||||
}
|
||||
}
|
||||
|
||||
async fn resolve(self) -> Self::AsyncOutput {
|
||||
futures::future::join_all(self.items.into_iter().enumerate().map(
|
||||
|(index, item)| {
|
||||
let (_, view) = (self.view_fn)(index, item);
|
||||
view.resolve()
|
||||
},
|
||||
))
|
||||
.await
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>()
|
||||
#[cfg(feature = "ssr")]
|
||||
{
|
||||
futures::future::join_all(
|
||||
self.ssr_items.into_iter().map(|(_, view)| view.resolve()),
|
||||
)
|
||||
.await
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
{
|
||||
futures::future::join_all(
|
||||
self.items.into_iter().flatten().enumerate().map(
|
||||
|(index, item)| {
|
||||
let (_, view) = (self.view_fn)(index, item);
|
||||
view.resolve()
|
||||
},
|
||||
),
|
||||
)
|
||||
.await
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn to_html_with_buf(
|
||||
self,
|
||||
buf: &mut String,
|
||||
@@ -255,8 +299,9 @@ where
|
||||
if mark_branches && escape {
|
||||
buf.open_branch("for");
|
||||
}
|
||||
for (index, item) in self.items.into_iter().enumerate() {
|
||||
let (_, item) = (self.view_fn)(index, item);
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
for item in self.ssr_items {
|
||||
if mark_branches && escape {
|
||||
buf.open_branch("item");
|
||||
}
|
||||
@@ -278,6 +323,7 @@ where
|
||||
buf.push_str("<!>");
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn to_html_async_with_buf<const OUT_OF_ORDER: bool>(
|
||||
self,
|
||||
buf: &mut StreamBuilder,
|
||||
@@ -289,13 +335,10 @@ where
|
||||
if mark_branches && escape {
|
||||
buf.open_branch("for");
|
||||
}
|
||||
for (index, item) in self.items.into_iter().enumerate() {
|
||||
let branch_name = mark_branches.then(|| {
|
||||
let key = (self.key_fn)(&item);
|
||||
let key = key.ser_key();
|
||||
format!("item-{key}")
|
||||
});
|
||||
let (_, item) = (self.view_fn)(index, item);
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
for (key, item) in self.ssr_items {
|
||||
let branch_name = mark_branches.then(|| format!("item-{key}"));
|
||||
if mark_branches && escape {
|
||||
buf.open_branch(branch_name.as_ref().unwrap());
|
||||
}
|
||||
@@ -311,6 +354,7 @@ where
|
||||
}
|
||||
*position = Position::NextChild;
|
||||
}
|
||||
|
||||
if mark_branches && escape {
|
||||
buf.close_branch("for");
|
||||
}
|
||||
@@ -334,11 +378,11 @@ where
|
||||
.expect("parent of keyed list should be an element");
|
||||
|
||||
// build list
|
||||
let items = self.items.into_iter();
|
||||
let items = self.items.into_iter().flatten();
|
||||
let (capacity, _) = items.size_hint();
|
||||
let mut hashed_items =
|
||||
FxIndexSet::with_capacity_and_hasher(capacity, Default::default());
|
||||
let mut rendered_items = Vec::new();
|
||||
let mut rendered_items = Vec::with_capacity(capacity);
|
||||
for (index, item) in items.enumerate() {
|
||||
hashed_items.insert((self.key_fn)(&item));
|
||||
let (set_index, view) = (self.view_fn)(index, item);
|
||||
@@ -373,11 +417,11 @@ where
|
||||
.expect("parent of keyed list should be an element");
|
||||
|
||||
// build list
|
||||
let items = self.items.into_iter();
|
||||
let items = self.items.into_iter().flatten();
|
||||
let (capacity, _) = items.size_hint();
|
||||
let mut hashed_items =
|
||||
FxIndexSet::with_capacity_and_hasher(capacity, Default::default());
|
||||
let mut rendered_items = Vec::new();
|
||||
let mut rendered_items = Vec::with_capacity(capacity);
|
||||
for (index, item) in items.enumerate() {
|
||||
hashed_items.insert((self.key_fn)(&item));
|
||||
let (set_index, view) = (self.view_fn)(index, item);
|
||||
|
||||
@@ -3,8 +3,13 @@ use crate::{
|
||||
html::attribute::any_attribute::AnyAttribute, hydration::Cursor,
|
||||
ssr::StreamBuilder,
|
||||
};
|
||||
use parking_lot::RwLock;
|
||||
use std::{cell::RefCell, future::Future, rc::Rc, sync::Arc};
|
||||
use or_poisoned::OrPoisoned;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
future::Future,
|
||||
rc::Rc,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
/// Add attributes to typed views.
|
||||
pub mod add_attr;
|
||||
@@ -476,12 +481,12 @@ impl PositionState {
|
||||
|
||||
/// Sets the current position.
|
||||
pub fn set(&self, position: Position) {
|
||||
*self.0.write() = position;
|
||||
*self.0.write().or_poisoned() = position;
|
||||
}
|
||||
|
||||
/// Gets the current position.
|
||||
pub fn get(&self) -> Position {
|
||||
*self.0.read()
|
||||
*self.0.read().or_poisoned()
|
||||
}
|
||||
|
||||
/// Creates a new [`PositionState`], which starts with the same [`Position`], but no longer
|
||||
|
||||
Reference in New Issue
Block a user