commonMain.net.folivo.trixnity.client.store.RoomStateStore.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of trixnity-client-jvm Show documentation
Show all versions of trixnity-client-jvm Show documentation
Multiplatform Kotlin SDK for matrix-protocol
package net.folivo.trixnity.client.store
import io.ktor.util.reflect.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import net.folivo.trixnity.client.MatrixClientConfiguration
import net.folivo.trixnity.client.store.cache.MapDeleteByRoomIdRepositoryObservableCache
import net.folivo.trixnity.client.store.cache.MapRepositoryCoroutinesCacheKey
import net.folivo.trixnity.client.store.repository.RepositoryTransactionManager
import net.folivo.trixnity.client.store.repository.RoomStateRepository
import net.folivo.trixnity.client.store.repository.RoomStateRepositoryKey
import net.folivo.trixnity.core.model.RoomId
import net.folivo.trixnity.core.model.events.ClientEvent.StateBaseEvent
import net.folivo.trixnity.core.model.events.RedactedEventContent
import net.folivo.trixnity.core.model.events.StateEventContent
import net.folivo.trixnity.core.model.events.UnknownEventContent
import net.folivo.trixnity.core.serialization.events.EventContentSerializerMappings
import kotlin.reflect.KClass
class RoomStateStore(
private val roomStateRepository: RoomStateRepository,
private val tm: RepositoryTransactionManager,
private val contentMappings: EventContentSerializerMappings,
config: MatrixClientConfiguration,
storeScope: CoroutineScope,
) : Store {
private val roomStateCache = MapDeleteByRoomIdRepositoryObservableCache(
roomStateRepository,
tm,
storeScope,
config.cacheExpireDurations.roomState
) { it.firstKey.roomId }
override suspend fun clearCache() = deleteAll()
override suspend fun deleteAll() {
roomStateCache.deleteAll()
}
suspend fun deleteByRoomId(roomId: RoomId) {
roomStateCache.deleteByRoomId(roomId)
}
private fun findType(eventContentClass: KClass): String {
return contentMappings.state.find { it.kClass == eventContentClass }?.type
?: throw IllegalArgumentException("Cannot find state event, because it is not supported. You need to register it first.")
}
suspend fun save(event: StateBaseEvent<*>, skipWhenAlreadyPresent: Boolean = false) {
val roomId = event.roomId
val stateKey = event.stateKey
if (roomId != null) {
val eventType = when (val content = event.content) {
is UnknownEventContent -> content.eventType
is RedactedEventContent -> content.eventType
else -> contentMappings.state.find { it.kClass.isInstance(event.content) }?.type
}
?: throw IllegalArgumentException("Cannot find state event, because it is not supported. You need to register it first.")
if (skipWhenAlreadyPresent)
roomStateCache.write(
MapRepositoryCoroutinesCacheKey(
RoomStateRepositoryKey(roomId, eventType),
stateKey
)
) {
it ?: event
}
else
roomStateCache.write(
MapRepositoryCoroutinesCacheKey(
RoomStateRepositoryKey(roomId, eventType),
stateKey
), event
)
}
}
@OptIn(ExperimentalCoroutinesApi::class)
fun get(
roomId: RoomId,
eventContentClass: KClass,
): Flow