Commit Graph

4 Commits

Author SHA1 Message Date
d94c546450 fix: recompile after saving direct edits
Saving wrote the v2 document but nothing else, and `/api/state` serves the
outputs of the last compile — so a refresh showed the pre-edit geometry and a
successful save was indistinguishable from a failed one. Reported as "saved,
refreshed, edit gone"; the document on disk was in fact correct, resolving as
`exact` with the constraint reaching the profile.

Save now recompiles and clears the preview overlay, since the baseline carries
the edit afterwards and would otherwise draw it twice. The recompile is reported
separately from the save: if it fails the message says the edit was saved and
names the compile error, rather than claiming the save failed.

The existing identity test could not have caught this. An ignored `editsFile`
and an empty document produce the same output, so it proved nothing about a
non-empty one. The API test now compiles with and without a saved constraint and
asserts the outputs differ.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 09:25:09 +08:00
38593f6f67 feat: save, undo and redo direct edits
Step 5 of the map editor. EditSession becomes the single owner of the constraint
set, replacing the pair of refs step 4 kept alongside it: it now holds the saved
operations too, and `fragment()` assembles the constraints plus every operation
they reference — the shape both preview and save send. That removes the class of
bug that produced the earlier 400, because callers can no longer ship a
constraint whose provenance points at nothing.

Save goes through `expectedDocumentVersion`. A 409 adopts the server's version so
the next attempt is checked against reality, and says which version won instead
of failing silently. Undo of a saved gesture appends an inverse operation rather
than rewriting persisted history; undo of an unsaved one just moves the cursor.
Discard drops unsaved commands, cancels anything in flight, and returns the map
to the baseline.

One gesture mints one operation id, released on pointerup. Reusing an id across
gestures put two operations with the same id in the document, which
validateEditDocument() rejects.

The API test now covers the payload the client actually sends — `constraints` +
`operations` merged into the active document, rather than a whole document — and
asserts that a save survives a reload as `exact`. Sending constraints without
their operations is asserted to be rejected rather than written.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 18:11:52 +08:00
f3f763f94c feat: persist direct edits with revision rebase 2026-08-27 12:52:40 +08:00
41c314fc61 feat: add direct edit preview APIs 2026-08-27 12:48:29 +08:00