From 3f157574493ed27cd086b8a550ae6ccce669b236 Mon Sep 17 00:00:00 2001 From: Terry Yiu Date: Fri, 11 Sep 2026 07:21:56 +0300 Subject: [PATCH] Fix stale docs claiming web persistence is in-memory only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Web actually persists via localStorage (LocalStorageStores.kt), which survives page reloads — only SQLDelight itself isn't used there, since its web driver needs a worker plus a wasm sqlite binary. The doc comments and AGENTS.md still described the in-memory state this replaced. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01FXcrACM5sok3M1KQJ8kByy --- AGENTS.md | 17 ++++++++--------- .../tyiu/satsprice/data/db/SqlDelightStores.kt | 4 ++-- .../satsprice/data/db/LocalStorageStores.kt | 9 +++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 49e2b98..ca06560 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,12 +12,9 @@ and Android (see README's Supported Platforms/Download and Install). Web and Desktop/JVM are real future release targets too — `desktopApp` already has full native packaging configured (DMG/MSI/DEB, see its `build.gradle.kts`) — but neither has a release/CI pipeline set up yet, so treat them as -not-yet-shipped rather than dev-only. Web specifically also has no real -persistence yet (see `data/db/SqlDelightStores.kt`'s doc comment: no -SQLDelight driver, in-memory only, nothing survives a page reload) — worth -keeping in mind if that platform's release plans firm up. The app converts -between BTC, Sats, and fiat currencies using live exchange rates (Coinbase, -CoinGecko, or a manually typed-in rate). +not-yet-shipped rather than dev-only. The app converts between BTC, Sats, +and fiat currencies using live exchange rates (Coinbase, CoinGecko, or a +manually typed-in rate). This is a from-scratch rewrite of an earlier Skip-based (Swift-transpiled-to- Kotlin) implementation — `main` is now this Kotlin Multiplatform project. @@ -146,9 +143,11 @@ to call. SQLDelight (`data/db/SqlDelightStores.kt` + platform-specific driver `actual`s) backs `ExchangeRateStore`/`SelectedCurrenciesStore`/ `SelectedSourceStore`, each exposed via an `expect fun createXStore()` -factory. Web has no real SQLDelight driver — it gets an in-memory-only -fallback (nothing persists across a page reload). This is a known gap to -close if/when Web's release plans firm up, not a permanent design choice. +factory. Web has no real SQLDelight driver — SQLDelight's web driver needs a +worker plus a wasm sqlite binary — so it gets a `localStorage`-backed +fallback instead (`data/db/LocalStorageStores.kt`), which does survive page +reloads, just scoped to the browser profile/origin (cleared by clearing +site data, not shared across browsers/devices). ## Testing and verification diff --git a/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/data/db/SqlDelightStores.kt b/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/data/db/SqlDelightStores.kt index 1c019a3..9dbd8fb 100644 --- a/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/data/db/SqlDelightStores.kt +++ b/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/data/db/SqlDelightStores.kt @@ -10,8 +10,8 @@ import kotlin.time.Instant /** * Shared by every platform that opens a real [AppDatabase] (Android, Desktop, iOS/macOS) — only * driver construction differs per platform, so that's the only expect/actual boundary needed. - * Web isn't a shipped platform (see README's Supported Platforms) and gets an in-memory fallback - * instead of a real driver. + * Web has no real SQLDelight driver and uses a `localStorage`-backed fallback instead (see + * `LocalStorageStores.kt`). */ internal class SqlDelightExchangeRateStore(private val database: AppDatabase) : ExchangeRateStore { override suspend fun loadLastKnownRates(sourceId: String): ExchangeRates? = withContext(Dispatchers.Default) { diff --git a/shared/src/webMain/kotlin/xyz/tyiu/satsprice/data/db/LocalStorageStores.kt b/shared/src/webMain/kotlin/xyz/tyiu/satsprice/data/db/LocalStorageStores.kt index 331217a..2a12a3c 100644 --- a/shared/src/webMain/kotlin/xyz/tyiu/satsprice/data/db/LocalStorageStores.kt +++ b/shared/src/webMain/kotlin/xyz/tyiu/satsprice/data/db/LocalStorageStores.kt @@ -10,10 +10,11 @@ import xyz.tyiu.satsprice.data.ExchangeRates import kotlin.time.Instant /** - * Web isn't a shipped platform (see README's Supported Platforms) and SQLDelight's web driver - * needs a worker plus a wasm sqlite binary, so persistence here goes through the browser's - * localStorage instead of a real database — plenty for this small amount of data, and it - * survives page reloads unlike the in-memory state it replaced. + * SQLDelight's web driver needs a worker plus a wasm sqlite binary, so persistence here goes + * through the browser's localStorage instead of a real database — plenty for this small amount + * of data, and it survives page reloads like the other platforms' real databases do. Scoped to + * the browser profile/origin, though: it won't survive a cleared site data / private window, and + * doesn't sync or back up anywhere. */ private val json = Json { ignoreUnknownKeys = true }