refactor: core:data -> core:data:client

This commit is contained in:
Cilly Leang 2026-04-02 21:55:45 +11:00
parent 4cdb9a305c
commit e7caeca356
Signed by: cilly
GPG key ID: 6500251E087653C9
21 changed files with 162 additions and 78 deletions

View file

@ -2,9 +2,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.kotlinSerialization)
alias(libs.plugins.androidMultiplatformLibrary)
alias(libs.plugins.ksp)
}
kotlin {
@ -27,26 +25,8 @@ kotlin {
jvm()
sourceSets {
androidMain.dependencies {
implementation(libs.koin.compose)
implementation(libs.ktor.client.okhttp)
}
commonMain.dependencies {
implementation(libs.okio)
implementation(libs.koin.core)
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.contentnegotiation)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.datetime)
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.serialization.protobuf)
implementation(projects.core)
implementation(projects.core.room)
}
iosMain.dependencies {
implementation(libs.ktor.client.darwin)
}
}
}

View file

@ -0,0 +1,54 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.kotlinSerialization)
alias(libs.plugins.androidMultiplatformLibrary)
alias(libs.plugins.ksp)
}
kotlin {
android {
namespace = "moe.lava.banksia.core.data.client"
compileSdk = libs.versions.android.compileSdk.get().toInt()
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
}
}
compilerOptions {
freeCompilerArgs.add("-opt-in=kotlin.time.ExperimentalTime")
}
iosArm64()
iosSimulatorArm64()
jvm()
sourceSets {
androidMain.dependencies {
implementation(libs.koin.compose)
implementation(libs.ktor.client.okhttp)
}
commonMain.dependencies {
api(projects.core.data)
implementation(libs.okio)
implementation(libs.koin.core)
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.contentnegotiation)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.datetime)
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.serialization.protobuf)
implementation(projects.core)
implementation(projects.core.room)
}
iosMain.dependencies {
implementation(libs.ktor.client.darwin)
}
}
}

View file

@ -8,6 +8,9 @@ import io.ktor.client.plugins.plugin
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json
import moe.lava.banksia.core.Constants
import moe.lava.banksia.core.data.repositories.ClientRouteRepository
import moe.lava.banksia.core.data.repositories.ClientStopRepository
import moe.lava.banksia.core.data.repositories.ClientStopTimeRepository
import moe.lava.banksia.core.data.repositories.RouteRepository
import moe.lava.banksia.core.data.repositories.StopRepository
import moe.lava.banksia.core.data.repositories.StopTimeRepository
@ -21,9 +24,10 @@ import moe.lava.banksia.core.room.roomDiModule
import moe.lava.banksia.core.util.log
import moe.lava.banksia.data.ptv.PtvService
import org.koin.core.module.dsl.singleOf
import org.koin.dsl.bind
import org.koin.dsl.module
val dataDiModule = module {
val clientDataDiModule = module {
includes(roomDiModule)
// HTTP Clients
@ -56,7 +60,7 @@ val dataDiModule = module {
singleOf(::StopTimeRemoteDataSource)
// Repositories
singleOf(::RouteRepository)
singleOf(::StopRepository)
singleOf(::StopTimeRepository)
singleOf(::ClientRouteRepository) bind RouteRepository::class
singleOf(::ClientStopRepository) bind StopRepository::class
singleOf(::ClientStopTimeRepository) bind StopTimeRepository::class
}

View file

@ -0,0 +1,25 @@
package moe.lava.banksia.core.data.repositories
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import moe.lava.banksia.core.data.sources.route.RouteLocalDataSource
import moe.lava.banksia.core.data.sources.route.RouteRemoteDataSource
internal class ClientRouteRepository internal constructor(
private val local: RouteLocalDataSource,
private val remote: RouteRemoteDataSource,
) : RouteRepository {
private val mutex = Mutex()
override suspend fun getAll() = mutex.withLock {
local
.getAll()
.map { it.asModel() }
.ifEmpty {
remote
.getAll()
.also { local.save(*it.toTypedArray()) }
}
}
override suspend fun get(id: String) = mutex.withLock { local.get(id)?.asModel() ?: remote.get(id) }
}

View file

@ -0,0 +1,22 @@
package moe.lava.banksia.core.data.repositories
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import moe.lava.banksia.core.data.sources.stop.StopLocalDataSource
import moe.lava.banksia.core.data.sources.stop.StopRemoteDataSource
internal class ClientStopRepository internal constructor(
private val local: StopLocalDataSource,
private val remote: StopRemoteDataSource,
) : StopRepository {
private val mutex = Mutex()
override suspend fun get(id: String) = mutex.withLock { local.get(id)?.asModel() ?: remote.get(id) }
override suspend fun getByRoute(id: String) = mutex.withLock {
local
.getByRoute(id)
.map { it.asModel() }
.ifEmpty { null }
?: remote.getByRoute(id)
}
}

View file

@ -0,0 +1,16 @@
package moe.lava.banksia.core.data.repositories
import moe.lava.banksia.core.data.sources.stoptime.StopTimeLocalDataSource
import moe.lava.banksia.core.data.sources.stoptime.StopTimeRemoteDataSource
import moe.lava.banksia.core.model.StopTimeDated
internal class ClientStopTimeRepository internal constructor(
private val local: StopTimeLocalDataSource,
private val remote: StopTimeRemoteDataSource,
) : StopTimeRepository {
override suspend fun getForStop(id: String): List<StopTimeDated> {
return local
.getAtStop(id)
.ifEmpty { remote.getAtStop(id) }
}
}

View file

@ -0,0 +1,21 @@
plugins {
alias(libs.plugins.kotlinJvm)
alias(libs.plugins.kotlinSerialization)
}
kotlin {
compilerOptions {
freeCompilerArgs.add("-opt-in=kotlin.time.ExperimentalTime")
}
}
dependencies {
implementation(libs.okio)
implementation(libs.koin.core)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.datetime)
api(projects.core.data)
implementation(projects.core)
implementation(projects.core.room)
}

View file

@ -1,25 +1,8 @@
package moe.lava.banksia.core.data.repositories
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import moe.lava.banksia.core.data.sources.route.RouteLocalDataSource
import moe.lava.banksia.core.data.sources.route.RouteRemoteDataSource
import moe.lava.banksia.core.model.Route
class RouteRepository internal constructor(
private val local: RouteLocalDataSource,
private val remote: RouteRemoteDataSource,
) {
private val mutex = Mutex()
suspend fun getAll() = mutex.withLock {
local
.getAll()
.map { it.asModel() }
.ifEmpty {
remote
.getAll()
.also { local.save(*it.toTypedArray()) }
}
}
suspend fun get(id: String) = mutex.withLock { local.get(id)?.asModel() ?: remote.get(id) }
interface RouteRepository {
suspend fun get(id: String): Route
suspend fun getAll(): List<Route>
}

View file

@ -1,22 +1,8 @@
package moe.lava.banksia.core.data.repositories
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import moe.lava.banksia.core.data.sources.stop.StopLocalDataSource
import moe.lava.banksia.core.data.sources.stop.StopRemoteDataSource
import moe.lava.banksia.core.model.Stop
class StopRepository internal constructor(
private val local: StopLocalDataSource,
private val remote: StopRemoteDataSource,
) {
private val mutex = Mutex()
suspend fun get(id: String) = mutex.withLock { local.get(id)?.asModel() ?: remote.get(id) }
suspend fun getByRoute(id: String) = mutex.withLock {
local
.getByRoute(id)
.map { it.asModel() }
.ifEmpty { null }
?: remote.getByRoute(id)
}
interface StopRepository {
suspend fun get(id: String): Stop
suspend fun getByRoute(id: String): List<Stop>
}

View file

@ -1,16 +1,7 @@
package moe.lava.banksia.core.data.repositories
import moe.lava.banksia.core.data.sources.stoptime.StopTimeLocalDataSource
import moe.lava.banksia.core.data.sources.stoptime.StopTimeRemoteDataSource
import moe.lava.banksia.core.model.StopTimeDated
class StopTimeRepository internal constructor(
private val local: StopTimeLocalDataSource,
private val remote: StopTimeRemoteDataSource,
) {
suspend fun getForStop(id: String): List<StopTimeDated> {
return local
.getAtStop(id)
.ifEmpty { remote.getAtStop(id) }
}
interface StopTimeRepository {
suspend fun getForStop(id: String): List<StopTimeDated>
}

View file

@ -5,7 +5,7 @@ plugins {
application
}
group = "moe.lava.banksia"
group = "moe.lava.banksia.server"
version = "1.0.0"
application {
mainClass.set("moe.lava.banksia.server.ApplicationKt")

View file

@ -37,6 +37,8 @@ include(":server:gtfs")
include(":server:gtfs_rt")
include(":core")
include(":core:data")
include(":core:data:client")
include(":core:data:server")
include(":core:room")
include(":ui")
include(":ui:maps")

View file

@ -68,7 +68,7 @@ kotlin {
implementation(libs.ui.backhandler)
implementation(projects.core)
implementation(projects.core.data)
implementation(projects.core.data.client)
implementation(projects.ui.maps)
implementation(projects.ui.shared)
}

View file

@ -1,12 +1,12 @@
package moe.lava.banksia.ui.di
import moe.lava.banksia.core.data.dataDiModule
import moe.lava.banksia.core.data.clientDataDiModule
import moe.lava.banksia.ui.screens.map.MapScreenViewModel
import org.koin.core.module.dsl.viewModelOf
import org.koin.dsl.module
val AppModule = module {
includes(dataDiModule)
includes(clientDataDiModule)
// ViewModel
viewModelOf(::MapScreenViewModel)