package dev.inmo.micro_utils.repos.cache import dev.inmo.micro_utils.pagination.Pagination import dev.inmo.micro_utils.pagination.PaginationResult import dev.inmo.micro_utils.repos.* import dev.inmo.micro_utils.repos.cache.cache.KVCache import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.* open class ReadKeyValueCacheRepo( protected open val parentRepo: ReadKeyValueRepo, protected open val kvCache: KVCache, ) : ReadKeyValueRepo by parentRepo { override suspend fun get(k: Key): Value? = kvCache.get(k) ?: parentRepo.get(k) ?.also { kvCache.set(k, it) } override suspend fun contains(key: Key): Boolean = kvCache.contains(key) || parentRepo.contains(key) } fun ReadKeyValueRepo.cached( kvCache: KVCache ) = ReadKeyValueCacheRepo(this, kvCache) open class KeyValueCacheRepo( parentRepo: KeyValueRepo, kvCache: KVCache, scope: CoroutineScope = CoroutineScope(Dispatchers.Default) ) : ReadKeyValueCacheRepo(parentRepo, kvCache), KeyValueRepo, WriteKeyValueRepo by parentRepo { protected val onNewJob = parentRepo.onNewValue.onEach { kvCache.set(it.first, it.second) }.launchIn(scope) protected val onRemoveJob = parentRepo.onValueRemoved.onEach { kvCache.unset(it) }.launchIn(scope) } fun KeyValueRepo.cached( kvCache: KVCache, scope: CoroutineScope = CoroutineScope(Dispatchers.Default) ) = KeyValueCacheRepo(this, kvCache, scope)