xxfast / KStore

A tiny Kotlin multiplatform library that assists in saving and restoring objects to and from disk using kotlinx.coroutines, kotlinx.serialisation and kotlinx.io
https://xxfast.github.io/KStore/
Apache License 2.0
540 stars 18 forks source link

FeatureRequest: Add the ability to use Indexed DB for JS and WasmJs #119

Open eygraber opened 2 months ago

eygraber commented 2 months ago

Like the title says, it would be nice to back the store in Indexed DB especially because it is async, performs better, and has a higher storage limit.

xxfast commented 2 months ago

Should be doable with a custom codec. Although not sure if it should be part of kstore 🤔

eygraber commented 2 months ago

I made a quick implementation using this indexeddb library. I guess once that is merged I can make a separate repo for providing that Codec. Any particular reason for it not being part of kstore (3rd party dependency, etc...)?

private inline fun <reified T : @Serializable Any> IndexedDbCodec(
  key: String,
  storeName: String,
  json: Json = DefaultJson,
  database: Database,
): IndexedDbCodec<T> = IndexedDbCodec(
  key = key,
  storeName = storeName,
  json = json,
  serializer = json.serializersModule.serializer(),
  database = database,
)

private class IndexedDbCodec<T : @Serializable Any>(
  private val key: String,
  private val storeName: String,
  private val json: Json,
  private val serializer: KSerializer<T>,
  private val database: Database,
) : Codec<T> {
  override suspend fun encode(value: T?) {
    database.writeTransaction(storeName) {
      val store = objectStore(storeName)
      if(value != null) {
        store.put(json.encodeToString(serializer, value).toJsString(), IDBKey(key))
      }
      else {
        store.delete(IDBKey(key))
      }
    }
  }

  override suspend fun decode(): T? = database.transaction(storeName) {
    val store = objectStore(storeName)
    runCatching {
      store.get(IDBKey(key)).unsafeCast<JsString>().toString()
    }.getOrNull()?.let {
      json.decodeFromString(serializer, it)
    }
  }
}
xxfast commented 2 months ago

Hi @eygraber

Thank you so much for the reply.

Any particular reason for it not being part of kstore (3rd party dependency, etc...)?

Yeah basically that. I initially wanted to limit 3rd party libraries down to just the kotlinx-libraries (hence this migration) but I don't see any harm in allowing a separate module for this, perhaps named kstore-indexed-db

Feel free to PR this in to my repo :) you should be able to use kstore-storage module (which uses the storage apis) as a template. I should be able to include those artifacts in the next release

eygraber commented 2 months ago

I'll open one soon. Waiting for a PR to get merged in to the 3rd party library that supports wasm.

apolostudio commented 1 month ago

any progress on this?