You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ObjectStackAdapter.batchTransaction now negotiates atomic cross-object batch
declaratively via the discovery capability bit (framework #3298) instead of
only probing at runtime.
- connect() reads capabilities.transactionalBatch from GET /api/v1/discovery
and records it as a tri-state (readTransactionalBatchCapability accepts both
the hierarchical `{ enabled }` wire shape and the flat boolean the client SDK
normalizes to).
- When the backend DECLARES support (true), batchTransaction trusts server
atomicity: it calls /batch and surfaces any failure — including 404/405/501 —
as a real error. No runtime probe, no non-atomic client-side compensation.
- When the capability is false or ABSENT (backend predates #3298), the legacy
runtime-probe + emulation fallback stays active so a save is still possible;
hard-removing it would regress older backends from "saves, less safe" to
"no save path" (#2679 compatibility constraint).
core's generic emulateBatchTransaction / runBatchTransaction are untouched and
remain the fallback for adapters with no server-side transaction.
Docs: adapter README + data-source guide document the capability table and the
minimum-backend note (atomicity guaranteed only against backends advertising
the capability — framework #3298 / #1604). Adds tests for each capability state
and a unit test for the shape reader.
Picks up #2679 acceptance item 4; unblocked by framework#3298 (merged).
Claude-Session: https://claude.ai/code/session_01U1UuBuaurza8a2XWSUaDQr
Co-authored-by: Claude <noreply@anthropic.com>
|`true`|**Trusts server atomicity.** Calls `/batch`; any failure — including `404`/`405`/`501` — surfaces as a real error. No non-atomic client-side fallback. |
306
+
|`false`| Backend can't do an atomic batch (route absent, or a runtime without transactions) → falls back to the non-atomic client-side emulation below. |
307
+
|*absent*| Backend predates #3298 and advertises nothing → the legacy runtime probe stays: try `/batch`, and on `404`/`405`/`501` fall back to emulation. |
308
+
309
+
The hierarchical wire shape (`{ transactionalBatch: { enabled: true } }`) and the
310
+
flat form the client SDK normalizes to (`{ transactionalBatch: true }`) are both
311
+
accepted.
312
+
313
+
### Non-atomic fallback
314
+
315
+
When the capability is `false` or absent, the adapter degrades to a client-side
316
+
emulation (`@object-ui/core`'s `emulateBatchTransaction`): the operations run in
317
+
order and, on failure, it best-effort deletes the records it created (children
318
+
before parent) before rethrowing. This is **not** a transaction — a create's
319
+
side effects (hooks, rollups, webhooks) are not undone by a later delete, and a
320
+
mid-batch network drop leaves no chance to compensate. It exists only so a save
321
+
is still possible against a backend that lacks server atomicity; removing it
322
+
would turn "saves, less safe" into "no save path" on older backends
0 commit comments