Add atomic transaction API#28
Conversation
|
Warning Review limit reached
Next review available in: 45 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (4)
📒 Files selected for processing (10)
WalkthroughAdds atomic batch SQL execution end-to-end: new message types, coordinator routing for batch requests, transactional batch execution in the database layer, and a WASM-exported ChangesBatch transaction support
Tooling updates
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
c959ab8 to
0f66c72
Compare
0f66c72 to
118472a
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Cargo.toml`:
- Line 52: The `wasm-bindgen-utils` dependency pin is mismatched with the
current `prelude` imports, since
`wasm_bindgen_utils::prelude::serde_wasm_bindgen` is not available in the
crates.io release. Update the affected call sites to import and use
`serde_wasm_bindgen` directly, or keep the existing git-pinned revision of
`wasm-bindgen-utils` so the `prelude` paths used by the relevant modules
continue to compile.
In `@flake.nix`:
- Around line 63-66: The Foundry setup in the task is running from the repo root
instead of the rain.math.float submodule, so update the sequence in the flake
task to change into lib/rain.math.float before invoking any forge commands.
Ensure the soldeer dependency install happens first, then run forge install and
forge build from that directory so the commands target the correct project and
use its local Foundry config.
In `@packages/sqlite-web/src/db.rs`:
- Around line 122-123: The params extraction in `Db::...` is swallowing
`Reflect::get` failures by converting them to `undefined`, unlike the `sql`
getter path. Update the `params` property access to propagate the error instead
of defaulting to `JsValue::UNDEFINED`, using the same error-handling style as
the existing `sql` getter logic so a throwing `params` getter does not execute
silently.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: fe61f091-285f-490c-a549-13cf7e1ef03b
⛔ Files ignored due to path filters (4)
Cargo.lockis excluded by!**/*.lockflake.lockis excluded by!**/*.locksvelte-test/bun.lockis excluded by!**/*.locksvelte-test/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (10)
Cargo.tomlflake.nixlib/rain.math.floatpackages/sqlite-web-core/src/coordination.rspackages/sqlite-web-core/src/database.rspackages/sqlite-web-core/src/messages.rspackages/sqlite-web/src/db.rsscripts/local-bundle.shsvelte-test/package.jsonsvelte-test/tests/integration/transaction-interleaving.test.ts
118472a to
6b6364f
Compare
6b6364f to
c13d19d
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/sqlite-web-core/src/database.rs`:
- Around line 927-929: The SQL filtering in `database.rs` is incorrectly
treating any string where `Self::first_sql_keyword(sql)` returns `None` as
trivia-only, which skips executable statements prefixed by a delimiter and can
also hide invalid transaction-control input. Update the logic around the
`first_sql_keyword` check so it distinguishes true comment/whitespace-only SQL
from non-trivia statements that merely lack a leading keyword, and make the
transaction path fail with an error and rollback instead of continuing silently.
Use the existing `Self::first_sql_keyword` and surrounding transaction execution
flow to route delimiter-prefixed SQL into either normal execution or an explicit
rejected-statement error.
- Around line 944-949: The batch execution logic is counting affected rows from
`statement_result` even when the statement returns rows, which can pick up stale
`sqlite3_changes()` from prior DML. Update the handling around
`exec_prepared_statement` so only non-query statements contribute to
`total_affected_rows`, and make sure `last_statement_rows`/`affected` are
separated by whether the statement actually returned rows. Use the existing
`statement_result` match in `database.rs` to gate the increment and avoid
carrying over changes from SELECT-like statements.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8fef518b-b173-4c55-a863-f3b31559057a
⛔ Files ignored due to path filters (4)
Cargo.lockis excluded by!**/*.lockflake.lockis excluded by!**/*.locksvelte-test/bun.lockis excluded by!**/*.locksvelte-test/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (10)
Cargo.tomlflake.nixlib/rain.math.floatpackages/sqlite-web-core/src/coordination.rspackages/sqlite-web-core/src/database.rspackages/sqlite-web-core/src/messages.rspackages/sqlite-web/src/db.rsscripts/local-bundle.shsvelte-test/package.jsonsvelte-test/tests/integration/transaction-interleaving.test.ts
c13d19d to
df6914e
Compare

Dependent PRs
1586a5973882b6acb72c2677c29ad23c4c6f85effor the submodule commit that narrows Alloy features so the latest float crate compiles with sqlite-web.Motivation
Consumers that pass
SQLiteWasmDatabase.query.bind(localDb)into SDK transaction batches currently express logical transactions as separatequery()calls:BEGIN TRANSACTION, individual statements, thenCOMMIT. sqlite-web serializes individual worker messages, but it does not hold a transaction-level lock across multiplequery()calls. With multiple handles/tabs sharing a database, those split transaction calls can interleave and SQLite can returncannot start a transaction within a transaction.Solution
SQLiteWasmDatabase.transaction(statements)JS API that accepts{ sql, params? }[].BEGIN,COMMIT,END,ROLLBACK,SAVEPOINT,RELEASE) so the worker owns transaction scope.BEGINinterleaving failure.wipeAndRecreatehandles Chrome briefly retaining OPFS handles.revm 36.build-submodulesbefore runningforge build.Checks
By submitting this for review, I am confirming I have done the following:
Validation run:
cargo fmt --allcargo check --tests -p sqlite-web-corecargo check --tests -p sqlite-web./scripts/local-bundle.shbun run test(158 passed | 4 skipped)npm run lint-format-checkinsvelte-testnix develop -c rustc --version(rustc 1.94.0)nix develop -c build-submodulesnix develop -c local-bundleNO_HEADLESSwasm browser test forsqlite-web-core(98 passed; 0 failed)NO_HEADLESSwasm browser test forsqlite-web(38 passed; 0 failedbefore OPFS retry; CI rerun pending)git diff --checkSummary by CodeRabbit
New Features
transaction(statements)API to run multiple SQL statements atomically.Bug Fixes
Tests
Chores