소스 검색

Fix side-by-side fragments by walking in reverse (#2841)

* got a repro, but no solution :(

* hmmmmm 🤔

* awyayayayayayya

* omg it's because we dont create in rev

* Make nodes rev

* fix tests compile

* Clean up PR

* revert changes to native

* Clean up PR, add test
Jonathan Kelley 10 달 전
부모
커밋
2f30c73678
4개의 변경된 파일184개의 추가작업 그리고 180개의 파일을 삭제
  1. 78 171
      Cargo.lock
  2. 45 4
      packages/core/src/diff/node.rs
  3. 53 0
      packages/core/tests/many_roots.rs
  4. 8 5
      packages/interpreter/src/write_native_mutations.rs

+ 78 - 171
Cargo.lock

@@ -893,7 +893,7 @@ dependencies = [
  "rustls-pemfile 2.1.3",
  "rustls-pki-types",
  "tokio",
- "tokio-rustls 0.26.0",
+ "tokio-rustls",
  "tower",
  "tower-service",
 ]
@@ -1175,7 +1175,7 @@ dependencies = [
  "ahash 0.8.11",
  "chrono",
  "either",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "itertools 0.13.0",
  "nom",
  "once_cell",
@@ -1332,7 +1332,7 @@ dependencies = [
  "heck 0.5.0",
  "home",
  "ignore",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "indicatif",
  "liquid",
  "liquid-core",
@@ -1411,12 +1411,13 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.1.10"
+version = "1.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292"
+checksum = "5fb8dd288a69fc53a1996d7ecfbf4a20d59065bff137ce7e56bbd620de191189"
 dependencies = [
  "jobserver",
  "libc",
+ "shlex",
 ]
 
 [[package]]
@@ -2157,9 +2158,9 @@ dependencies = [
 
 [[package]]
 name = "cxx"
-version = "1.0.124"
+version = "1.0.125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "273dcfd3acd4e1e276af13ed2a43eea7001318823e7a726a6b3ed39b4acc0b82"
+checksum = "fa01254578b9046d93c2e150ab5837be49d31ee482522a4cd71d92347fbb325c"
 dependencies = [
  "cc",
  "cxxbridge-flags",
@@ -2169,9 +2170,9 @@ dependencies = [
 
 [[package]]
 name = "cxx-build"
-version = "1.0.124"
+version = "1.0.125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8b2766fbd92be34e9ed143898fce6c572dc009de39506ed6903e5a05b68914e"
+checksum = "3db0add730d3d9a8c662490c50afc7c1ff48f8f0442aa40a9f85aafa3669e696"
 dependencies = [
  "cc",
  "codespan-reporting",
@@ -2184,15 +2185,15 @@ dependencies = [
 
 [[package]]
 name = "cxxbridge-flags"
-version = "1.0.124"
+version = "1.0.125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "839fcd5e43464614ffaa989eaf1c139ef1f0c51672a1ed08023307fa1b909ccd"
+checksum = "22b540401b8aaaadb41beb096a762f7a2b34eb36b496a5d205e9f019530960e3"
 
 [[package]]
 name = "cxxbridge-macro"
-version = "1.0.124"
+version = "1.0.125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b2c1c1776b986979be68bb2285da855f8d8a35851a769fca8740df7c3d07877"
+checksum = "70c463609d2d980b8300ca12d14b05c6a72bed5c37143581903e82526716484e"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2440,7 +2441,7 @@ dependencies = [
  "headers 0.3.9",
  "html_parser",
  "hyper 1.4.1",
- "hyper-rustls 0.27.2",
+ "hyper-rustls",
  "hyper-util",
  "ignore",
  "krates",
@@ -2453,7 +2454,7 @@ dependencies = [
  "proc-macro2",
  "ratatui",
  "rayon",
- "reqwest 0.12.5",
+ "reqwest",
  "rsx-rosetta",
  "rustls 0.23.12",
  "serde",
@@ -2519,7 +2520,7 @@ dependencies = [
  "manganis",
  "pretty_assertions",
  "rand 0.8.5",
- "reqwest 0.12.5",
+ "reqwest",
  "rustc-hash 1.1.0",
  "rustversion",
  "serde",
@@ -2578,7 +2579,7 @@ dependencies = [
  "objc",
  "objc_id",
  "rand 0.8.5",
- "reqwest 0.12.5",
+ "reqwest",
  "rfd",
  "rustc-hash 1.1.0",
  "separator",
@@ -2610,7 +2611,7 @@ dependencies = [
  "http-range",
  "manganis",
  "rand 0.8.5",
- "reqwest 0.12.5",
+ "reqwest",
  "separator",
  "serde",
  "serde_json",
@@ -2655,7 +2656,7 @@ dependencies = [
  "generational-box",
  "http 1.1.0",
  "hyper 1.4.1",
- "hyper-rustls 0.27.2",
+ "hyper-rustls",
  "once_cell",
  "parking_lot",
  "pin-project",
@@ -2684,7 +2685,7 @@ dependencies = [
  "futures-channel",
  "futures-util",
  "generational-box",
- "reqwest 0.12.5",
+ "reqwest",
  "rustversion",
  "slab",
  "tokio",
@@ -2942,7 +2943,7 @@ dependencies = [
  "once_cell",
  "parking_lot",
  "rand 0.8.5",
- "reqwest 0.12.5",
+ "reqwest",
  "rustc-hash 1.1.0",
  "serde",
  "simple_logger",
@@ -3648,7 +3649,7 @@ version = "0.1.0"
 dependencies = [
  "chrono",
  "dioxus",
- "reqwest 0.12.5",
+ "reqwest",
  "serde",
  "tracing",
  "tracing-subscriber",
@@ -3660,7 +3661,7 @@ name = "fullstack-hello-world-example"
 version = "0.1.0"
 dependencies = [
  "dioxus",
- "reqwest 0.12.5",
+ "reqwest",
  "serde",
  "simple_logger",
  "tracing",
@@ -4369,9 +4370,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
 
 [[package]]
 name = "global-hotkey"
-version = "0.5.4"
+version = "0.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89cb13e8c52c87e28a46eae3e5e65b8f0cd465c4c9e67b13d56c70412e792bc3"
+checksum = "b436093d1598b05e3b7fddc097b2bad32763f53a1beb25ab6f9718c6a60acd09"
 dependencies = [
  "bitflags 2.6.0",
  "cocoa",
@@ -4500,15 +4501,15 @@ dependencies = [
 
 [[package]]
 name = "gloo-net"
-version = "0.5.0"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173"
+checksum = "c06f627b1a58ca3d42b45d6104bf1e1a03799df472df00988b6ba21accc10580"
 dependencies = [
  "futures-channel",
  "futures-core",
  "futures-sink",
  "gloo-utils 0.2.0",
- "http 0.2.12",
+ "http 1.1.0",
  "js-sys",
  "pin-project",
  "serde",
@@ -4674,7 +4675,7 @@ dependencies = [
  "futures-sink",
  "futures-util",
  "http 0.2.12",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "slab",
  "tokio",
  "tokio-util",
@@ -4693,7 +4694,7 @@ dependencies = [
  "futures-core",
  "futures-sink",
  "http 1.1.0",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "slab",
  "tokio",
  "tokio-util",
@@ -5075,20 +5076,6 @@ dependencies = [
  "want",
 ]
 
-[[package]]
-name = "hyper-rustls"
-version = "0.24.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
-dependencies = [
- "futures-util",
- "http 0.2.12",
- "hyper 0.14.30",
- "rustls 0.21.12",
- "tokio",
- "tokio-rustls 0.24.1",
-]
-
 [[package]]
 name = "hyper-rustls"
 version = "0.27.2"
@@ -5104,7 +5091,7 @@ dependencies = [
  "rustls-native-certs",
  "rustls-pki-types",
  "tokio",
- "tokio-rustls 0.26.0",
+ "tokio-rustls",
  "tower-service",
  "webpki-roots 0.26.3",
 ]
@@ -5121,19 +5108,6 @@ dependencies = [
  "tokio-io-timeout",
 ]
 
-[[package]]
-name = "hyper-tls"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
-dependencies = [
- "bytes",
- "hyper 0.14.30",
- "native-tls",
- "tokio",
- "tokio-native-tls",
-]
-
 [[package]]
 name = "hyper-tls"
 version = "0.6.0"
@@ -5320,9 +5294,9 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "2.3.0"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0"
+checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
 dependencies = [
  "equivalent",
  "hashbrown 0.14.5",
@@ -5490,11 +5464,11 @@ dependencies = [
 
 [[package]]
 name = "is-terminal"
-version = "0.4.12"
+version = "0.4.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b"
+checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
 dependencies = [
- "hermit-abi 0.3.9",
+ "hermit-abi 0.4.0",
  "libc",
  "windows-sys 0.52.0",
 ]
@@ -5822,7 +5796,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
 dependencies = [
  "cfg-if",
- "windows-targets 0.48.5",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -6123,7 +6097,7 @@ dependencies = [
  "railwind",
  "ravif",
  "rayon",
- "reqwest 0.12.5",
+ "reqwest",
  "rustc-hash 1.1.0",
  "serde",
  "serde_json",
@@ -6144,7 +6118,7 @@ dependencies = [
  "built",
  "home",
  "infer 0.11.0",
- "reqwest 0.12.5",
+ "reqwest",
  "serde",
  "toml 0.7.8",
  "tracing",
@@ -7106,7 +7080,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
 dependencies = [
  "fixedbitset",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
 ]
 
 [[package]]
@@ -7320,7 +7294,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
 dependencies = [
  "base64 0.22.1",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "quick-xml",
  "serde",
  "time",
@@ -8054,53 +8028,6 @@ dependencies = [
  "bytecheck",
 ]
 
-[[package]]
-name = "reqwest"
-version = "0.11.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
-dependencies = [
- "base64 0.21.7",
- "bytes",
- "encoding_rs",
- "futures-core",
- "futures-util",
- "h2 0.3.26",
- "http 0.2.12",
- "http-body 0.4.6",
- "hyper 0.14.30",
- "hyper-rustls 0.24.2",
- "hyper-tls 0.5.0",
- "ipnet",
- "js-sys",
- "log",
- "mime",
- "mime_guess",
- "native-tls",
- "once_cell",
- "percent-encoding",
- "pin-project-lite",
- "rustls 0.21.12",
- "rustls-pemfile 1.0.4",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sync_wrapper 0.1.2",
- "system-configuration",
- "tokio",
- "tokio-native-tls",
- "tokio-rustls 0.24.1",
- "tokio-util",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "wasm-streams",
- "web-sys",
- "webpki-roots 0.25.4",
- "winreg 0.50.0",
-]
-
 [[package]]
 name = "reqwest"
 version = "0.12.5"
@@ -8118,13 +8045,14 @@ dependencies = [
  "http-body 1.0.1",
  "http-body-util",
  "hyper 1.4.1",
- "hyper-rustls 0.27.2",
- "hyper-tls 0.6.0",
+ "hyper-rustls",
+ "hyper-tls",
  "hyper-util",
  "ipnet",
  "js-sys",
  "log",
  "mime",
+ "mime_guess",
  "native-tls",
  "once_cell",
  "percent-encoding",
@@ -8140,7 +8068,7 @@ dependencies = [
  "system-configuration",
  "tokio",
  "tokio-native-tls",
- "tokio-rustls 0.26.0",
+ "tokio-rustls",
  "tokio-util",
  "tower-service",
  "url",
@@ -8270,7 +8198,7 @@ checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
 dependencies = [
  "base64 0.21.7",
  "bitflags 2.6.0",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "serde",
  "serde_derive",
 ]
@@ -8403,7 +8331,6 @@ version = "0.21.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
 dependencies = [
- "log",
  "ring",
  "rustls-webpki 0.101.7",
  "sct",
@@ -8773,7 +8700,7 @@ dependencies = [
  "chrono",
  "hex",
  "indexmap 1.9.3",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "serde",
  "serde_derive",
  "serde_json",
@@ -8795,23 +8722,23 @@ dependencies = [
 
 [[package]]
 name = "server_fn"
-version = "0.6.13"
+version = "0.6.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9aaae169927ef701a4734d680adcb08f13269c9f0af822bf175d681fe56d65c"
+checksum = "024b400db1aca5bd4188714f7bbbf7a2e1962b9a12a80b2a21e937e509086963"
 dependencies = [
  "axum 0.7.5",
  "bytes",
  "const_format",
  "dashmap",
  "futures",
- "gloo-net 0.5.0",
+ "gloo-net 0.6.0",
  "http 1.1.0",
  "http-body-util",
  "hyper 1.4.1",
  "inventory",
  "js-sys",
  "once_cell",
- "reqwest 0.11.27",
+ "reqwest",
  "send_wrapper",
  "serde",
  "serde_json",
@@ -8830,9 +8757,9 @@ dependencies = [
 
 [[package]]
 name = "server_fn_macro"
-version = "0.6.13"
+version = "0.6.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "583085903fd5d091884eb52d99550e32777015af21f0f5dbec49bedcc320ce82"
+checksum = "9cf0e6f71fc924df36e87f27dfbd447f0bedd092d365db3a5396878256d9f00c"
 dependencies = [
  "const_format",
  "convert_case 0.6.0",
@@ -8844,9 +8771,9 @@ dependencies = [
 
 [[package]]
 name = "server_fn_macro_default"
-version = "0.6.13"
+version = "0.6.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b628649700e28cf8bc33e0df5de5c9d591a1828ba005a25b425477055f1e0e74"
+checksum = "556e4fd51eb9ee3e7d9fb0febec6cef486dcbc8f7f427591dfcfebee1abe1ad4"
 dependencies = [
  "server_fn_macro",
  "syn 2.0.74",
@@ -9211,7 +9138,7 @@ dependencies = [
  "futures-util",
  "hashlink",
  "hex",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "ipnetwork",
  "log",
  "mac_address",
@@ -9600,7 +9527,7 @@ dependencies = [
  "base64 0.21.7",
  "dashmap",
  "either",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "jsonc-parser",
  "lru 0.10.1",
  "once_cell",
@@ -9741,7 +9668,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4740e53eaf68b101203c1df0937d5161a29f3c13bceed0836ddfe245b72dd000"
 dependencies = [
  "anyhow",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "serde",
  "serde_json",
  "sourcemap",
@@ -9847,7 +9774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bd07cbb52c1ac41115c9ddd5a4d046a7388008bd950b61a48df7f7f490f19827"
 dependencies = [
  "arrayvec",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "is-macro",
  "serde",
  "serde_derive",
@@ -10067,7 +9994,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5d75a42254926bad8b7fa9390767a18ac608d99cfd5a3be675e4739c2cf7db1b"
 dependencies = [
  "arrayvec",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "num-bigint",
  "num_cpus",
  "once_cell",
@@ -10125,7 +10052,7 @@ checksum = "e85162c77f8c80b55e5aed3a5e5477b74a53ce9cca05dec6e3dabec1de0f49af"
 dependencies = [
  "anyhow",
  "dashmap",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "once_cell",
  "preset_env_base",
  "rustc-hash 1.1.0",
@@ -10170,7 +10097,7 @@ checksum = "7c0a71579d030e12fd3cfbfc8712c4ce21afc526f2a759903c77d8df61950f5e"
 dependencies = [
  "better_scoped_tls",
  "bitflags 2.6.0",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "once_cell",
  "phf 0.11.2",
  "rustc-hash 1.1.0",
@@ -10206,7 +10133,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4bb500b65423646da940e289ad37e7c88332d7194248c33fc63a9e768e104fe5"
 dependencies = [
  "arrayvec",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "is-macro",
  "num-bigint",
  "serde",
@@ -10256,7 +10183,7 @@ dependencies = [
  "Inflector",
  "anyhow",
  "bitflags 2.6.0",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "is-macro",
  "path-clean 1.0.1",
  "pathdiff",
@@ -10281,7 +10208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "17446e46b75654901d962251ec4d0063423ee81759a325ed82fcf073308d97ca"
 dependencies = [
  "dashmap",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "once_cell",
  "petgraph",
  "rustc-hash 1.1.0",
@@ -10326,7 +10253,7 @@ checksum = "c3e54a8c87d90812bf69b0f07931bb629111a3f24efe83b9190c3a40a5ebc25e"
 dependencies = [
  "base64 0.21.7",
  "dashmap",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "once_cell",
  "serde",
  "sha1",
@@ -10366,7 +10293,7 @@ version = "0.30.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bbb53b6fec4526660cc460f581b049a7f4bfb26b4b5d70aa0930c70abecf2f46"
 dependencies = [
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "rustc-hash 1.1.0",
  "swc_atoms",
  "swc_common",
@@ -10383,7 +10310,7 @@ version = "0.134.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cde8f1ef3f7bd53340c7bd679f1ec563a45225ac8fb63f22d6de1ff4b345475d"
 dependencies = [
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "num_cpus",
  "once_cell",
  "rustc-hash 1.1.0",
@@ -10441,7 +10368,7 @@ version = "0.25.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "357e2c97bb51431d65080f25b436bc4e2fc1a7f64a643bc21a8353e478dc799f"
 dependencies = [
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "petgraph",
  "rustc-hash 1.1.0",
  "swc_common",
@@ -10977,16 +10904,6 @@ dependencies = [
  "tokio",
 ]
 
-[[package]]
-name = "tokio-rustls"
-version = "0.24.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
-dependencies = [
- "rustls 0.21.12",
- "tokio",
-]
-
 [[package]]
 name = "tokio-rustls"
 version = "0.26.0"
@@ -11070,7 +10987,7 @@ version = "0.8.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
 dependencies = [
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "serde",
  "serde_spanned",
  "toml_datetime",
@@ -11092,7 +11009,7 @@ version = "0.19.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
 dependencies = [
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "serde",
  "serde_spanned",
  "toml_datetime",
@@ -11105,7 +11022,7 @@ version = "0.20.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
 dependencies = [
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "toml_datetime",
  "winnow 0.5.40",
 ]
@@ -11116,7 +11033,7 @@ version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
 dependencies = [
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "toml_datetime",
  "winnow 0.5.40",
 ]
@@ -11127,7 +11044,7 @@ version = "0.22.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
 dependencies = [
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "serde",
  "serde_spanned",
  "toml_datetime",
@@ -11214,9 +11131,9 @@ dependencies = [
 
 [[package]]
 name = "tower-layer"
-version = "0.3.2"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
+checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
 
 [[package]]
 name = "tower-service"
@@ -11993,7 +11910,7 @@ dependencies = [
  "ahash 0.8.11",
  "bitflags 2.6.0",
  "hashbrown 0.14.5",
- "indexmap 2.3.0",
+ "indexmap 2.4.0",
  "semver 1.0.23",
  "serde",
 ]
@@ -12535,16 +12452,6 @@ dependencies = [
  "memchr",
 ]
 
-[[package]]
-name = "winreg"
-version = "0.50.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
-dependencies = [
- "cfg-if",
- "windows-sys 0.48.0",
-]
-
 [[package]]
 name = "winreg"
 version = "0.51.0"

+ 45 - 4
packages/core/src/diff/node.rs

@@ -694,9 +694,50 @@ impl VNode {
         dom: &mut VirtualDom,
         mut to: Option<&mut impl WriteMutations>,
     ) {
-        // Only take nodes that are under this root node
-        let from_root_node = |(_, path): &(usize, &[u8])| path.first() == Some(&root_idx);
-        while let Some((dynamic_node_id, path)) = dynamic_nodes_iter.next_if(from_root_node) {
+        fn collect_dyn_node_range(
+            dynamic_nodes: &mut Peekable<impl Iterator<Item = (usize, &'static [u8])>>,
+            root_idx: u8,
+        ) -> Option<(usize, usize)> {
+            let start = match dynamic_nodes.peek() {
+                Some((idx, [first, ..])) if *first == root_idx => *idx,
+                _ => return None,
+            };
+
+            let mut end = start;
+
+            while let Some((idx, p)) =
+                dynamic_nodes.next_if(|(_, p)| matches!(p, [idx, ..] if *idx == root_idx))
+            {
+                if p.len() == 1 {
+                    continue;
+                }
+
+                end = idx;
+            }
+
+            Some((start, end))
+        }
+
+        let (start, end) = match collect_dyn_node_range(dynamic_nodes_iter, root_idx) {
+            Some((a, b)) => (a, b),
+            None => return,
+        };
+
+        // !!VERY IMPORTANT!!
+        //
+        // We need to walk the dynamic nodes in reverse order because we are going to replace the
+        // placeholder with the new nodes, which will invalidate our paths into the template.
+        // If we go in reverse, we leave a "wake of destruction" in our path, but our next iteration
+        // will still be "clean" since we only invalidated downstream nodes.
+        //
+        // Forgetting to do this will cause weird bugs like:
+        //  https://github.com/DioxusLabs/dioxus/issues/2809
+        //
+        // Which are quite serious.
+        // There might be more places in this codebase where we need to do `.rev()`
+        let reversed_iter = (start..=end).rev();
+
+        for dynamic_node_id in reversed_iter {
             let m = self.create_dynamic_node(
                 &self.dynamic_nodes[dynamic_node_id],
                 mount,
@@ -708,7 +749,7 @@ impl VNode {
                 // If we actually created real new nodes, we need to replace the placeholder for this dynamic node with the new dynamic nodes
                 if m > 0 {
                     // The path is one shorter because the top node is the root
-                    let path = &path[1..];
+                    let path = &self.template.node_paths[dynamic_node_id][1..];
                     to.replace_placeholder_with_nodes(path, m);
                 }
             }

+ 53 - 0
packages/core/tests/many_roots.rs

@@ -0,0 +1,53 @@
+#![allow(non_snake_case)]
+
+use dioxus::dioxus_core::Mutation::*;
+use dioxus::prelude::*;
+use dioxus_core::ElementId;
+
+/// Should push the text node onto the stack and modify it
+#[test]
+fn many_roots() {
+    fn app() -> Element {
+        rsx! {
+            div {
+                MyNav {}
+                MyOutlet {}
+            }
+        }
+    }
+
+    fn MyNav() -> Element {
+        rsx!(
+            div { "trailing nav" }
+            div { "whhhhh"}
+            div { "bhhhh" }
+        )
+    }
+
+    fn MyOutlet() -> Element {
+        rsx!(
+            div { "homepage 1" }
+        )
+    }
+
+    let mut dom = VirtualDom::new(app);
+    let edits = dom.rebuild_to_vec();
+
+    assert_eq!(
+        edits.edits,
+        [
+            // load the div {} container
+            LoadTemplate { index: 0, id: ElementId(1) },
+            // Load myoutlet first
+            LoadTemplate { index: 0, id: ElementId(2) },
+            ReplacePlaceholder { path: &[1], m: 1 },
+            // Then the MyNav
+            LoadTemplate { index: 0, id: ElementId(3) },
+            LoadTemplate { index: 1, id: ElementId(4) },
+            LoadTemplate { index: 2, id: ElementId(5) },
+            ReplacePlaceholder { path: &[0], m: 3 },
+            // Then mount the div to the dom
+            AppendChildren { m: 1, id: ElementId(0) },
+        ]
+    )
+}

+ 8 - 5
packages/interpreter/src/write_native_mutations.rs

@@ -97,14 +97,17 @@ impl WriteMutations for MutationState {
     fn load_template(&mut self, template: Template, index: usize, id: dioxus_core::ElementId) {
         // Get the template or create it if we haven't seen it before
         let tmpl_id = self.templates.get(&template).cloned().unwrap_or_else(|| {
-            let current_max_template_count = self.templates.len() as u16;
+            let tmpl_id = self.templates.len() as u16;
+            self.templates.insert(template, tmpl_id);
+
             for root in template.roots.iter() {
                 self.create_template_node(root);
-                self.templates.insert(template, current_max_template_count);
             }
-            let id = template.roots.len() as u16;
-            self.channel.add_templates(current_max_template_count, id);
-            current_max_template_count
+
+            let len = template.roots.len() as u16;
+            self.channel.add_templates(tmpl_id, len);
+
+            tmpl_id
         });
 
         self.channel