Open
Conversation
d3cca39 to
b34c9e2
Compare
b34c9e2 to
08b3d57
Compare
romac
pushed a commit
that referenced
this pull request
Jan 22, 2026
…-rs#1833) ## Summary This PR significantly improves the tree diffing and DOM patching infrastructure: ### facet-diff / cinereus improvements - Add `diff_trees_with_matching` to cinereus to expose the Matching alongside edit operations - Rewrite facet-diff's path conversion to use a shadow tree approach that tracks index shifts - Enable proper Move operation support in tree diff - Add `Properties` trait for node attributes (HTML/XML attributes) - Generate `UpdateAttribute` operations for matched nodes with differing attributes ### facet-html-diff - Implement Chawathe edit script semantics with slot-based displacement model - `InsertAt` and `Move` operations use `detach_to_slot` for displaced nodes - Proper path-to-DOM-index translation through type metadata ### facet-html-diff-wasm (NEW) - New crate for browser-based validation of DOM patching - Compiles to WASM, uses web-sys for real DOM manipulation - Uses `replaceChild` for atomic displacement with slot storage - Playwright test harness runs patches against real browser DOM ### Testing - Property tests verify roundtrip: `apply(A, diff(A, B)) == B` - 19 browser-based WASM tests validating real DOM behavior - 113+ facet-html-diff tests, 480+ total tests passing ### Documentation - Added `cinereus/CHAWATHE_SEMANTICS.md` documenting the displacement/slot model - Key insight: Chawathe INSERT/MOVE don't shift siblings - they displace to slots ## Chawathe Semantics The Chawathe algorithm uses **displacement** rather than **shifting**: ``` INSERT X at position 0, detach_to_slot: Some(1) → X takes position 0, previous occupant goes to slot #1 MOVE slot #1 to position 1, detach_to_slot: Some(2) → Node from slot #1 takes position 1, previous occupant goes to slot facet-rs#2 ``` This maps perfectly to DOM's `replaceChild(newNode, oldNode)` which atomically swaps and returns the displaced node. ## Test plan - [x] All 480 tests pass locally - [x] Property tests for roundtrip invariant - [x] Browser-based WASM tests with Playwright - [x] CI job for WASM browser testing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 New release
facet-core: 0.42.0 -> 0.43.0 (⚠ API breaking changes)facet-testhelpers-macros: 0.42.0 -> 0.43.0facet-testhelpers: 0.42.0 -> 0.43.0facet-macro-types: 0.42.0 -> 0.43.0facet-macro-parse: 0.42.0 -> 0.43.0facet-macros-impl: 0.42.0 -> 0.43.0 (✓ API compatible changes)facet-macros: 0.42.0 -> 0.43.0facet-reflect: 0.42.0 -> 0.43.0 (⚠ API breaking changes)facet: 0.42.0 -> 0.43.0 (✓ API compatible changes)facet-pretty: 0.42.0 -> 0.43.0facet-value: 0.42.0 -> 0.43.0cinereus: 0.42.0 -> 0.43.0facet-diff-core: 0.42.0 -> 0.43.0facet-diff: 0.42.0 -> 0.43.0facet-assert: 0.42.0 -> 0.43.0 (✓ API compatible changes)facet-path: 0.42.0 -> 0.43.0facet-singularize: 0.42.0 -> 0.43.0facet-solver: 0.42.0 -> 0.43.0facet-validate: 0.42.0 -> 0.42.1facet-format: 0.42.0 -> 0.42.1 (✓ API compatible changes)facet-xml: 0.42.0 -> 0.42.1 (✓ API compatible changes)facet-json: 0.42.0 -> 0.42.1 (✓ API compatible changes)facet-error: 0.42.0 -> 0.42.1facet-miette: 0.42.0 -> 0.42.1facet-default: 0.42.0 -> 0.42.1 (✓ API compatible changes)facet-args: 0.42.0 -> 0.43.0 (⚠ API breaking changes)facet-urlencoded: 0.42.0 -> 0.43.0facet-kdl: 0.42.0 -> 0.42.1 (✓ API compatible changes)facet-msgpack: 0.42.0 -> 0.42.1 (✓ API compatible changes)facet-postcard: 0.42.0 -> 0.42.1facet-toml: 0.42.0 -> 0.42.1 (✓ API compatible changes)facet-yaml: 0.42.0 -> 0.42.1 (✓ API compatible changes)facet-axum: 0.42.0 -> 0.43.0facet-json-schema: 0.42.0 -> 0.42.1facet-typescript: 0.42.0 -> 0.42.1facet-shapelike: 0.42.0 -> 0.42.1 (✓ API compatible changes)facet-svg: 0.42.0 -> 0.42.1facet-asn1: 0.42.0 -> 0.42.1 (✓ API compatible changes)facet-csv: 0.42.0 -> 0.42.1facet-xdr: 0.42.0 -> 0.42.1facet-html: 0.42.0 -> 0.42.1 (✓ API compatible changes)facet-html-dom: 0.42.0 -> 0.42.1facet-atom: 0.42.0 -> 0.42.1facet-tokio-postgres: 0.42.0 -> 0.42.1⚠
facet-corebreaking changes⚠
facet-reflectbreaking changes⚠
facet-argsbreaking changesChangelog
facet-corefacet-testhelpers-macrosfacet-testhelpersfacet-macro-typesfacet-macro-parsefacet-macros-implfacet-macrosfacet-reflectfacetfacet-prettyfacet-valuecinereusfacet-diff-corefacet-difffacet-assertfacet-pathfacet-singularizefacet-solverfacet-validatefacet-formatfacet-xmlfacet-jsonfacet-errorfacet-miettefacet-defaultfacet-argsfacet-kdlfacet-msgpackfacet-tomlfacet-yamlfacet-shapelikefacet-asn1facet-htmlfacet-tokio-postgresThis PR was generated with release-plz.