Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
eygraber opened this issue Aug 29, 2024 · 5 comments
Open
Labels
enhancement New feature or request

Comments

@eygraber
Copy link

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
Copy link
Owner

xxfast commented Sep 1, 2024

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

@eygraber
Copy link
Author

eygraber commented Sep 2, 2024

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
Copy link
Owner

xxfast commented Sep 3, 2024

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

@xxfast xxfast added the enhancement New feature or request label Sep 3, 2024
@eygraber
Copy link
Author

eygraber commented Sep 3, 2024

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

@apolostudio
Copy link

any progress on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants