mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 22:10:34 +00:00
Child order lives in the document as each container's :shapes vector, and the projection recorded it only as the global Euler intervals, so the index had no attribute a consumer could read to learn that a shape is the third child of its parent rather than the fourth. :shape/order is that attribute now: a plain 0-based integer, dense within one parent, declared in the schema beside :shape/id and written by the builder per shape from the parent's vector, exactly as the intervals are derived from it. The intervals keep their purpose, which is containment, and the ordinal does not answer a containment query. With an order in the index, :reorder-children stops being a skip. process-change carries :parent-id and :shapes, so the new arm writes the container's ordinals from that vector and retracts the ordinal of a child the vector no longer holds. The classification table's row moves to :covered, and the tier supports twenty-five of the thirty-nine change types rather than twenty-four. The applier's other gaps close beside it. The raw colour and typography reference ids ride in the index beside the resolved refs, so an asset added after the shape that named it repairs every shape that was waiting for it. A token name written onto a taken name displaces the holder as one retraction rather than refusing. Every declared shape attribute names its writer, so an attribute cannot be added to the schema and to no writer. And a batch that skipped or dropped a change marks the session stale, so both read gates refuse rather than answer from an index that disagrees with the document. Measured on a 5,101-object page: 20,411 datoms before one insertion and 20,412 after, of which one is the new shape's ordinal and none touches a shape already present, so an append rewrites no sibling while a deletion rewrites the ordinals after it (9,997 of them for the hundredth child) and a move pays the interval renumbering it already paid. backend-tests.graph-overlay-sync-test: 23 tests, 203 assertions, 0 failures. Entry: pp:graph:sibling-order-needs-an-authored-attribute open -> done Entry: pp:graph:mirror-the-reorder-children-change open -> done Entry: pp:graph:store-the-raw-asset-ref open -> done Entry: pp:graph:mirror-the-token-name-displacements open -> done Entry: pp:graph:pin-the-attribute-vocabulary open -> done Entry: pp:graph:does-a-set-token-carry-its-id open -> answered Entry: pp:graph:stale-index-gate open -> done Entry: pp:graph:close-applier-coverage-gap open -> done AI-assisted-by: deepseek-flash