Skip to content

chore: migrate persistence to async SQLDelight on JS [WPB-23964]#3982

Draft
Garzas wants to merge 8 commits intodevelopfrom
chore/sqldelight-js-async-migration
Draft

chore: migrate persistence to async SQLDelight on JS [WPB-23964]#3982
Garzas wants to merge 8 commits intodevelopfrom
chore/sqldelight-js-async-migration

Conversation

@Garzas
Copy link
Copy Markdown
Contributor

@Garzas Garzas commented Mar 19, 2026

https://wearezeta.atlassian.net/browse/WPB-23964


PR Submission Checklist for internal contributors

  • The PR Title

    • conforms to the style of semantic commits messages¹ supported in Wire's Github Workflow²
    • contains a reference JIRA issue number like SQPIT-764
    • answers the question: If merged, this PR will: ... ³
  • The PR Description

    • is free of optional paragraphs and you have filled the relevant parts to the best of your ability

Issues

  • Kalium JS persistence was using SQLDelight’s official web-worker-driver, but the persistence layer still assumed synchronous generated SQLDelight APIs.
  • This caused runtime failures on Kotlin/JS with the async driver, including IllegalStateException: The driver used with SQLDelight is asynchronous, so SQLDelight should be configured for asynchronous usage.
  • Enabling generateAsync = true for Kalium databases caused broad compile fallout because DAO, bootstrap, and helper code still depended on synchronous query access patterns.
  • JS persistence lacked an internal smoke validation proving that Kalium could open a DB, write, read, and avoid the async-driver crash.

Causes (Optional)

  • SQLDelight’s worker-based JS driver is asynchronous and returns async query results, while Kalium persistence helpers and generated-query call sites were written around synchronous SQLDelight behavior.
  • Some common DB bootstrap and migration helpers were typed around synchronous schema/query abstractions, which made them incompatible with JS async generation.
  • Native targets still rely on synchronous drivers, so the migration needed to preserve JVM/Android/iOS behavior without introducing JS-only branching across the common persistence API.

Solutions

  • Enabled SQLDelight async generation for both UserDatabase and GlobalDatabase in data:persistence.
  • Migrated affected persistence code to async-compatible SQLDelight access by replacing synchronous generated-query usage with async/suspending equivalents and propagating suspend where required through DAOs and helpers.
  • Updated database bootstrap and migration code to use async-compatible schema and FK-check paths, while keeping native targets working through synchronous schema/driver adaptation.
  • Kept the official SQLDelight JS worker-driver approach and added JS-specific worker setup needed to create the driver inside Kalium.
  • Added a Kalium-side JS smoke test that exercises real persistence behavior by opening the DB, performing a write, performing a read, and validating that the async-driver exception does not occur.
  • Added TODO markers to the current JS-only file-management stubs (nuke, DB path, empty file creation) so the remaining non-native parity gaps are explicit.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 19, 2026

Test Results

4 342 tests   - 380   4 300 ✅  - 305   8m 2s ⏱️ + 5m 10s
   10 suites  - 770      20 💤  -  97 
   10 files    - 770      22 ❌ + 22 

For more details on these failures, see this check.

Results for commit d3bde34. ± Comparison against base commit fb16f31.

This pull request removes 4722 and adds 4342 tests. Note that renamed tests count towards both.
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpAssetMessage_whenRestoring_thenShouldReadTheSameContent[js, browser]
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpAssetMessage_whenRestoring_thenShouldReadTheSameContent[jvm]
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpLocationMessage_whenRestoring_thenShouldReadTheSameContent[js, browser]
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpLocationMessage_whenRestoring_thenShouldReadTheSameContent[jvm]
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpReactions_whenRestoring_thenShouldReadTheSameContent[js, browser]
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpReactions_whenRestoring_thenShouldReadTheSameContent[jvm]
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpTextMessages_whenRestoring_thenShouldReadTheSameContent[js, browser]
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpTextMessages_whenRestoring_thenShouldReadTheSameContent[jvm]
com.wire.backup.BackupEndToEndTest ‑ givenBackupWithPassword_whenPeeking_thenShouldBeEncrypted[js, browser]
com.wire.backup.BackupEndToEndTest ‑ givenBackupWithPassword_whenPeeking_thenShouldBeEncrypted[jvm]
…
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpAssetMessage_whenRestoring_thenShouldReadTheSameContent
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpLocationMessage_whenRestoring_thenShouldReadTheSameContent
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpReactions_whenRestoring_thenShouldReadTheSameContent
com.wire.backup.BackupEndToEndTest ‑ givenBackedUpTextMessages_whenRestoring_thenShouldReadTheSameContent
com.wire.backup.BackupEndToEndTest ‑ givenBackupWithPassword_whenPeeking_thenShouldBeEncrypted
com.wire.backup.BackupEndToEndTest ‑ givenBackupWithoutPassword_whenPeeking_thenShouldNotBeEncrypted
com.wire.backup.BackupEndToEndTest ‑ givenEncryptedBackedUpTextMessages_whenRestoring_thenShouldReadTheSameContent
com.wire.backup.data.BackupContentTextTest ‑ givenMultipleValidMentions_whenCreatingText_thenShouldNotThrow
com.wire.backup.data.BackupContentTextTest ‑ givenNegativeStart_whenCreatingMention_thenShouldThrowIAE
com.wire.backup.data.BackupContentTextTest ‑ givenNoMentions_whenCreatingText_thenShouldNotThrow
…
This pull request removes 117 skipped tests and adds 20 skipped tests. Note that renamed tests count towards both.
com.wire.kalium.api.common.ACMEApiTest ‑ whenCallingGeTrustAnchorsApi_theResponseShouldBeConfigureCorrectly[jvm]
com.wire.kalium.api.common.ACMEApiTest ‑ whenCallingSendChallengeRequestApi_theResponseShouldBeConfigureCorrectly[jvm]
com.wire.kalium.api.v0.user.register.RegisterApiV0Test ‑ givenAValidEmail_whenActivationEmailWIthCode_theRequestShouldBeConfiguredCorrectly[jvm]
com.wire.kalium.api.v0.user.register.RegisterApiV0Test ‑ givenAValidEmail_whenRegisteringAccountWithEMail_theRequestShouldBeConfiguredCorrectly[jvm]
com.wire.kalium.api.v0.user.register.RegisterApiV0Test ‑ givenAValidEmail_whenSendingActivationEmail_theRequestShouldBeConfiguredCorrectly[jvm]
com.wire.kalium.api.v0.user.register.RegisterApiV0Test ‑ givenActivationCodeFail_thenErrorIsPropagated[jvm]
com.wire.kalium.api.v0.user.register.RegisterApiV0Test ‑ givenRegistrationFail_whenRegisteringAccountWithEMMail_thenErrorIsPropagated[jvm]
com.wire.kalium.api.v0.user.register.RegisterApiV0Test ‑ givenSendActivationCodeFail_thenErrorIsPropagated[jvm]
com.wire.kalium.cryptography.CryptoUtilsTest ‑ givenDummyText_whenEncryptedAndDecryptedWithAES256_returnsOriginalText[js, browser]
com.wire.kalium.cryptography.CryptoUtilsTest ‑ givenSomeDummyFile_whenEncryptedAndDecryptedWithAES256_returnsExpectedOriginalFile[js, browser]
…
com.wire.kalium.api.common.ACMEApiTest ‑ whenCallingGeTrustAnchorsApi_theResponseShouldBeConfigureCorrectly
com.wire.kalium.api.common.ACMEApiTest ‑ whenCallingSendChallengeRequestApi_theResponseShouldBeConfigureCorrectly
com.wire.kalium.api.v0.user.register.RegisterApiV0Test ‑ null
com.wire.kalium.cryptography.CryptoUtilsTest ‑ givenDummyText_whenEncryptedAndDecryptedWithAES256_returnsOriginalText
com.wire.kalium.cryptography.CryptoUtilsTest ‑ givenSomeDummyFile_whenEncryptedAndDecryptedWithAES256_returnsExpectedOriginalFile
com.wire.kalium.cryptography.CryptoUtilsTest ‑ givenSomeDummyFile_whenEncryptedAsAFileAndDecryptedWithAES256AsData_returnsExpectedOriginalFileContent
com.wire.kalium.cryptography.CryptoUtilsTest ‑ givenSomeDummyFile_whenEncryptedAsDataAndDecryptedWithAES256AsAFile_returnsExpectedOriginalFileContent
com.wire.kalium.cryptography.CryptoUtilsTest ‑ testGivenByteArray_whenCallingCalcMd5_returnsExpectedDigest
com.wire.kalium.cryptography.CryptoUtilsTest ‑ testGivenByteArray_whenCallingCalcSHA256_returnsExpectedDigest
com.wire.kalium.logic.data.conversation.ConversationRepositoryTest ‑ givenAGroupConversationHasNotNewMessages_whenGettingConversationDetails_ThenReturnZeroUnreadMessageCount
…

♻️ This comment has been updated with latest results.

@Garzas Garzas changed the title chore: migrate persistence to async SQLDelight on JS chore: migrate persistence to async SQLDelight on JS [WPB-23964] Apr 3, 2026
@datadog-wireapp
Copy link
Copy Markdown

datadog-wireapp bot commented Apr 3, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: d3bde34 | Docs | Was this helpful? Give us feedback!

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 3, 2026

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

🐰 Bencher Report

Branchchore/sqldelight-js-async-migration
Testbedubuntu-latest

⚠️ WARNING: No Threshold found!

Without a Threshold, no Alerts will ever be generated.

Click here to create a new Threshold
For more information, see the Threshold documentation.
To only post results if a Threshold exists, set the --ci-only-thresholds flag.

Click to view all benchmark results
BenchmarkLatencymicroseconds (µs)
com.wire.kalium.benchmarks.logic.CoreLogicBenchmark.createObjectInFiles📈 view plot
⚠️ NO THRESHOLD
926.50 µs
com.wire.kalium.benchmarks.logic.CoreLogicBenchmark.createObjectInMemory📈 view plot
⚠️ NO THRESHOLD
586,490.64 µs
com.wire.kalium.benchmarks.persistence.MessageReadBenchmark.inboxPagingDeepPageBenchmark📈 view plot
⚠️ NO THRESHOLD
131,375.89 µs
com.wire.kalium.benchmarks.persistence.MessageReadBenchmark.inboxPagingFirstPageBenchmark📈 view plot
⚠️ NO THRESHOLD
128,133.26 µs
com.wire.kalium.benchmarks.persistence.MessageReadBenchmark.localMarkAsReadBenchmark📈 view plot
⚠️ NO THRESHOLD
3,579.88 µs
com.wire.kalium.benchmarks.persistence.MessageReadBenchmark.messagePagingDeepPageBenchmark📈 view plot
⚠️ NO THRESHOLD
27,140.25 µs
com.wire.kalium.benchmarks.persistence.MessageReadBenchmark.messagePagingFirstPageBenchmark📈 view plot
⚠️ NO THRESHOLD
11,562.78 µs
com.wire.kalium.benchmarks.persistence.MessagesNoPragmaTuneBenchmark.messageInsertionBenchmark📈 view plot
⚠️ NO THRESHOLD
1,377,738.29 µs
com.wire.kalium.benchmarks.persistence.MessagesNoPragmaTuneBenchmark.queryMessagesBenchmark📈 view plot
⚠️ NO THRESHOLD
21,404.14 µs
🐰 View full continuous benchmarking report in Bencher

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants