feat(data-objectstack): gate non-atomic batch fallback on discovery transactionalBatch capability (#2693)#2755
Merged
Conversation
…ransactionalBatch capability (#2693) 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). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U1UuBuaurza8a2XWSUaDQr
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
os-zhuang
marked this pull request as ready for review
July 20, 2026 12:39
os-zhuang
added a commit
that referenced
this pull request
Jul 20, 2026
… SDK only (#2694) ObjectStackAdapter.batchTransaction now calls the typed SDK method client.data.batchTransaction(operations) directly; the transitional hand-rolled fetch('/api/v1/batch') branch is removed. Guaranteed present by the @objectstack/client@^16 dependency floor (framework #3271). Composes with the #2755 capability gate: a declared-atomic backend treats any failure as a real error; otherwise the SDK's status-decorated throw (404/405/501) still degrades to the non-atomic emulateBatchTransaction. Fallback tests reworked to drive via the SDK method. Docs + changeset updated. Closes #2694.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2693. Picks up #2679 acceptance item 4. Unblocked by framework#3298 (the discovery capability bit), which merged today.
Background
Until now
ObjectStackAdapter.batchTransactionlearned whether a backend could do an atomic cross-object/batchonly by firing one and reading the status (404/405 → no route, 501 → runtime without transactions), then degrading to the non-atomic client-side emulation in@object-ui/core. framework#3298 added a declarative signal so the client can decide at connect time instead.The contract (from framework#3298, merged)
Discovery now carries a capability bit. All three server producers (
rest-server,plugin-hono-server,metadata-protocol) emit the hierarchical shape and the client SDK normalizes it:discovery.capabilities.transactionalBatch.enabled: boolean@objectstack/client≥16.0.0-rc.1): flattened toclient.capabilities.transactionalBatch: booleantrue= route mounted and the runtime can honour a transaction (declared === enforced);false= neither; absent = backend predates #3298.Change
connect()readscapabilities.transactionalBatchinto a tri-state;batchTransactiongates its fallback on it:capabilities.transactionalBatchbatchTransactionbehaviourtrue/batch; any failure — incl. 404/405/501 — is a real error. No probe, no client-side compensation.false/batch, degrade to non-atomic emulation on 404/405/501.The reader accepts both the hierarchical
{ enabled }shape and the flat boolean the SDK normalizes to.Why the fallback is not hard-removed: #2679's compatibility note is explicit that deleting it against backends without
/batchturns "saves, less safe" into "no save path". So the compensation branch is gated off for declared-support backends (the modern path) but retained as the fallback forfalse/absent backends.@object-ui/core's genericemulateBatchTransaction/runBatchTransactionare untouched and remain the fallback for adapters with no server transaction (ValueDataSource,MockDataSource, …).Acceptance mapping (#2693)
ObjectStackAdapterno longer runs client-side compensation on the declared-support path (the branch survives only as the fallback for undeclared/false backends, per the 重构:master-detail 保存统一走原子 batchTransaction,把非原子回退隔离进适配器(承接 framework#1604 / framework ADR-0034 item 4) #2679 compat constraint).emulateBatchTransactionretained only for adapters without server transactions.Tests
true+ 404 / 501 → hard error, no client-side compensation.truenormalized identically./batch→ still emits one mutation event per op.false/ absent + 404 → still degrades to emulation (back-compat).readTransactionalBatchCapabilityacross hierarchical / flat / absent / malformed shapes.Full
unitproject green (252 files, 3454 tests);data-objectstack187/187; package type-check and eslint clean (only pre-existinganywarnings).Notes
@object-ui/data-objectstackminor.@objectstack/clientdependency bump needed — the capability is read from the discovery document the adapter already fetches, so the strict path works regardless of the installed client patch.🤖 Generated with Claude Code
Generated by Claude Code