Conditional room saves, so a stale save never overwrites another writer #5

Merged
oss merged 1 commit from feat/XSH-1-conditional-saves into selfhost 2026-11-11 12:52:08 +01:00
Owner

Part of Kaneo Live region shares for Excalidraw boards (XSH-1).

saveToFirebase (excalidraw-app/data/httpStorage.ts) used to snapshot the scene, read the room, and then PUT unconditionally. A save from another writer between that read and that PUT was overwritten. The other writer could be a second tab or the live-share bridge saving a guest's edit.

It now reads the room with its ETag, reconciles exactly as before, and PUTs with If-Match (or If-None-Match: * for a new room). On 412 it re-reads, reconciles and retries, up to 5 times. Against a backend without ETags it falls back to the previous unconditional PUT, so it can deploy in either order relative to oss/excalidraw-storage-backend#15.

The new test excalidraw-app/tests/httpStorage.test.ts races two saves on one room against an ETag-aware backend double. Both elements are kept. On the previous code the same test loses one. Typecheck, ESLint and Prettier are clean, and all 7 app tests pass. Reviewed by GPT-6.1-Sol: PASS.

🤖 Generated with Claude Code

Part of Kaneo *Live region shares for Excalidraw boards* (XSH-1). `saveToFirebase` (`excalidraw-app/data/httpStorage.ts`) used to snapshot the scene, read the room, and then PUT unconditionally. A save from another writer between that read and that PUT was overwritten. The other writer could be a second tab or the live-share bridge saving a guest's edit. It now reads the room with its ETag, reconciles exactly as before, and PUTs with `If-Match` (or `If-None-Match: *` for a new room). On 412 it re-reads, reconciles and retries, up to 5 times. Against a backend without ETags it falls back to the previous unconditional PUT, so it can deploy in either order relative to [oss/excalidraw-storage-backend#15](https://git.ossalali.com/oss/excalidraw-storage-backend/pulls/15). The new test `excalidraw-app/tests/httpStorage.test.ts` races two saves on one room against an ETag-aware backend double. Both elements are kept. On the previous code the same test loses one. Typecheck, ESLint and Prettier are clean, and all 7 app tests pass. Reviewed by GPT-6.1-Sol: PASS. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(selfhost): conditional room saves with retry, so a stale save never overwrites another writer's
All checks were successful
upkeep / dispatch (pull_request_target) Has been skipped
b692afd2b0
oss merged commit 6cd7be0e1c into selfhost 2026-11-11 12:52:08 +01:00
oss deleted branch feat/XSH-1-conditional-saves 2026-11-11 12:52:08 +01:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
oss/excalidraw!5
No description provided.