[WIP] feat(storage): use NitroSQLite 10.1 connections and statements - #851
Open
chrispader wants to merge 7 commits into
Open
chrispader wants to merge 7 commits into
chrispader wants to merge 7 commits into
Conversation
chrispader
force-pushed
the
@chrispader/chore/nitro-sqlite-10-peers
branch
from
September 28, 2026 12:02
1a8b643 to
1fa8054
Compare
chrispader
marked this pull request as ready for review
September 28, 2026 14:58
melvin-bot
Bot
requested review from
inimaga
and removed request for
a team
September 28, 2026 14:58
Contributor
|
@chrispader Is this ready for review? Held off looking at it since it has WIP in the title |
This was referenced Oct 1, 2026
Contributor
Author
@inimaga not yet! I'll ping you once this is ready 🙌🏼 |
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.
Onyx's SQLite provider sends reads and writes through one connection and prepares single-key queries on every call. Long reads can delay writes, while repeated queries incur preparation work. This PR adopts NitroSQLite 10.1.0's independent connections and prepared statements while preserving Onyx's read-after-write behavior and stored JSON format.
Details
The development dependency now uses the published NitroSQLite 10.1.0 package, with an optional peer requirement of ^10.1.0. The Node mock's better-sqlite3 dependency is updated to ^12.11.1, and the lockfile installs successfully. Latest Onyx main is merged into the branch.
The existing writer keeps atomic batch operations. A separate read-only connection handles lookups and full-store reads under WAL, and single-key get, set, and remove calls reuse prepared statements. Bulk writes and deletes group parameter sets so NitroSQLite can reuse a statement within each batch; only a final partial delete chunk needs different SQL.
Reads wait for writes that were already queued. A multiGet call split across several SQL queries uses one transaction snapshot, including when the writer commits during the read. Native DatabaseCannotBeOpened errors join the existing disk-pressure classification without importing the optional native runtime into the classifier.
The package upgrade also includes upstream transaction cleanup, connection ownership, NUL text handling, undefined parameter binding, row materialization improvements, Android temporary-storage handling, and bundled SQLite 3.53.4 with isolated symbols. RTree is available in the bundled engine; Onyx's key/value schema has no spatial queries. SEE encryption requires a licensed native build, a key supplied to both connections, and an App migration policy, so existing Onyx databases retain their current format. Onyx does not use NitroSQLite's TypeORM or vector adapters. The full upstream changes are listed in the 10.1.0 release.
The SQLite provider tests use the published react-native-nitro-sqlite/mock export, replacing Onyx's local mock. They execute real SQLite through better-sqlite3, with spies to control query timing. Onyx's public API and web provider behavior remain unchanged.
Related Issues
Expensify/App#102424
Linked E/App PR
Expensify/App#102422
Automated Tests
All 663 tests pass on the repository's pinned Node 24.19.0 after a clean lockfile install. The 39 SQLite provider tests use the published 10.1.0 mock and cover statement reuse, independent reads, read-after-write ordering, concurrent-write snapshots, and JSON merge behavior. New regressions cover grouped write and delete rollback, recovery after a failed snapshot read, full and partial delete chunks, and embedded NUL characters. Classifier tests cover structured native errors and legacy SQLite messages.
These Node tests verify provider behavior; native transaction fixes and performance still need App builds and device testing.
Manual Tests
The linked App PR needs to pin this branch's new head and use NitroSQLite 10.1.0 for validation. App CI and native device verification are pending.
In the linked App PR, upgrade iOS and Android builds with existing Onyx data, send a message, relaunch, and confirm the message and sign-in state persist. Repeat offline, reconnect, and confirm the pending message sends once. Export Onyx state from the developer tools and verify a known persisted key is present. Repeat with a high-traffic account to exercise chunked reads and writes.
Author Checklist
### Related Issuessection above### Linked E/App PRsection above, and verified this change against it (E/App CI passed and manual testing completed)TestssectiontoggleReportand notonIconClick).myBool && <MyComponent />.STYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)/** comment above it */thisproperly so there are no scoping issues (i.e.onClick={this.toggleReport}should be bound in the constructor).thisare necessary to be bound (i.e. avoid unnecessary binds)Avataris modified, I verified thatAvataris working as expected in all cases)mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
No screenshots or videos are included because this storage-provider change has no visible UI.
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari