Files
Meshtastic-Android/core/datastore
James RichandClaude Sonnet 5 54756a3265 feat(datastore): enable wasmJs via a platform-neutral Store abstraction
core:datastore wraps androidx.datastore.core.DataStore<T> for five
payload types (four proto messages plus a Preferences-backed store).
androidx.datastore:datastore -- the core artifact providing
DataStore/OkioSerializer/CorruptionException, not just the
-preferences extension core:prefs already hit -- publishes no wasmJs
variant at any version, confirmed against its Gradle Module Metadata.

Introduces Store<T> (core/datastore/store/Store.kt), a direct analog
to core:prefs's PrefsStore but simpler: each store here already holds
one whole serializable value, so no key/snapshot abstraction is
needed, just data/updateData mirroring DataStore<T>'s own two
members. nonWebMain's DataStoreAdapter wraps a real DataStore<T>
unchanged; wasmJsMain's LocalStorageStore is backed by localStorage,
running each payload's Wire ADAPTER.decode/.encode against an
in-memory okio.Buffer and base64-encoding the resulting bytes
(localStorage is string-only). Corruption policy mirrors the existing
Android/JVM ReplaceFileCorruptionHandler: no value yet or a value that
fails to decode both fall back to the default, with a decode failure
also logged and the recovered default written back so it isn't
re-hit on every access.

The four proto-payload DataSources (ChannelSetDataSource and friends)
needed zero logic changes -- they already depended only on
data/updateData, not on any other DataStore<T> member.

CorePreferencesDataStore (DataStore<Preferences>) has no wasmJs
counterpart: androidx.datastore.preferences's Preferences type itself
has no wasmJs variant, so there's no way to construct a Store<Preferences>
there at all -- this is the payload type being unavailable, not a
missing adapter. It and its three consumers
(RecentAddressesDataSource/BootloaderWarningDataSource/
FirmwareRecoveryDataSource) move to nonWebMain unchanged, deferred
rather than dropped -- a future pass could rewrite them against
core:prefs's own PrefsStore instead.

Caught before shipping: hoisting androidx.datastore/
androidx.datastore.preferences to nonWebMain-only initially demoted
them from api to implementation, mirroring core:prefs's precedent --
but androidApp's google flavor (GoogleMapsDataStore.kt/
GoogleMapsPrefs.kt) imports those packages directly with no dependency
of its own, relying entirely on this module's transitive api exposure.
Kept as api at the nonWebMain/commonMain level instead; verified via a
real compileGoogleDebugKotlin + testGoogleDebugUnitTest run, not just
the fdroid flavor the first pass checked.

CoreDatastoreWasmJsModule is not registered anywhere yet -- no webApp
module exists in this repo pass, same state as core:database's
SingleDatabaseProvider and core:prefs's CorePrefsWasmJsModule.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 22:43:26 -05:00
..

:core:datastore

Overview

Targets: Android · JVM (Desktop) · iOS

The :core:datastore module manages structured, asynchronous data storage using Jetpack DataStore. It is primarily used for storing complex configuration objects like radio channel sets and local device configurations.

Key Components

1. Data Sources

  • ChannelSetDataSource: Manages the storage of radio channel configurations.
  • LocalConfigDataSource / ModuleConfigDataSource: Store the connected device's LocalConfig and LocalModuleConfig protos.
  • LocalStatsDataSource: Stores the latest local device statistics telemetry.
  • RecentAddressesDataSource: Stores a list of recently connected radio addresses (BLE/USB/TCP).
  • BootloaderWarningDataSource / FirmwareRecoveryDataSource: Persist firmware-update safety state (bootloader warnings, pending recovery).

UI preferences live in :core:prefs (UiPrefs / UiPrefsImpl), not here.

2. Serializers

Uses Kotlin Serialization to convert between Protobuf/JSON and the underlying DataStore storage.

Dependency Graph

graph TB
  :core:datastore[datastore]:::kmp-library
  :core:datastore -.-> :core:common
  :core:datastore -.-> :core:model

classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef compose-desktop-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-library-compose fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library-compose fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;