mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
A wrapper baked its path at creation, so a reference held across a structural mutation kept addressing its old index: unshift then a write through a held element edited its neighbour, and a write after a splice could produce a path the replica cannot resolve. The baseline diff this tracker replaced was immune, because its dirty paths were only hints and the ops came from comparing values. A wrapper now holds a cell (parent link plus segment) and the path is walked at use time, so renumbering an element corrects every descendant. pop/shift/unshift/splice and length truncation shift live children by the delta and mark removed ones dead; sort/reverse/fill/copyWithin relocate them by identity. Renumbering iterates a set of live cells rather than the lookup cache, which is keyed by index and can evict a child that is still held. Writes through an element that left the document mutate it and record nothing, as plain JS and the baseline diff both do. One object can occupy several positions in the tree. A wrapper is now shared per target and holds a cell per position, and a write emits an op for each, which is what the baseline diff produced for the same shape. Positions are registered when a path is read, when a tracked value is assigned elsewhere, and when one is inserted by an array mutator (only the inserted range is examined; scanning the array made every structural mutation O(n)). A blocked view of an object gets its own wrapper so the reserved-key guard cannot be bypassed through a safe alias. Paths are cached per cell against a counter that only structural mutation bumps, and the per-write cell walk is skipped until a document actually aliases something. |
||
|---|---|---|
| .. | ||
| boundary.test.ts | ||
| bundle.test.ts | ||
| context.test.ts | ||
| delta.test.ts | ||
| facet-loader.test.ts | ||
| facets.test.ts | ||
| helpers.ts | ||
| json.test.ts | ||
| service-wire.test.ts | ||
| services.test.ts | ||