diff --git a/backend/.gitignore b/backend/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/backend/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts
new file mode 100644
index 0000000..1e5ea2a
--- /dev/null
+++ b/backend/build.gradle.kts
@@ -0,0 +1,21 @@
+plugins {
+ id("kotlin-platform-jvm")
+ application
+ kotlin("plugin.serialization")
+}
+
+dependencies {
+ implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${Versions.kotlin}")
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.kotlinCoroutines}")
+
+ implementation("io.ktor:ktor-server-core:${Versions.ktor}")
+ implementation("io.ktor:ktor-server-netty:${Versions.ktor}")
+ implementation("io.ktor:ktor-serialization:${Versions.ktor}")
+
+ implementation("ch.qos.logback:logback-classic:1.2.3")
+
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:${Versions.kotlinxSerialization}") // JVM dependency
+ implementation("io.ktor:ktor-websockets:${Versions.ktor}")
+
+ implementation(project(":common"))
+}
diff --git a/common/src/jvmMain/kotlin/com/surrus/Server.kt b/backend/src/main/kotlin/Server.kt
similarity index 59%
rename from common/src/jvmMain/kotlin/com/surrus/Server.kt
rename to backend/src/main/kotlin/Server.kt
index 222a759..b03e788 100644
--- a/common/src/jvmMain/kotlin/com/surrus/Server.kt
+++ b/backend/src/main/kotlin/Server.kt
@@ -1,23 +1,17 @@
-package com.surrus
-
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.serialization.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
-import org.litote.kmongo.*
-import org.litote.kmongo.async.*
-import org.litote.kmongo.coroutine.*
-import org.litote.kmongo.async.getCollection
-import com.mongodb.ConnectionString
import com.surrus.common.repository.PeopleInSpaceRepository
import io.ktor.application.call
import io.ktor.application.install
import io.ktor.features.ContentNegotiation
-import kotlinx.coroutines.GlobalScope
+import io.ktor.http.ContentType
+import io.ktor.http.content.resources
+import io.ktor.http.content.static
import kotlinx.coroutines.flow.collect
-import kotlinx.coroutines.launch
-import javax.xml.bind.JAXBElement
+
fun main() {
val repository = PeopleInSpaceRepository()
@@ -28,11 +22,23 @@ fun main() {
}
routing {
+
+ get("/") {
+ call.respondText(
+ this::class.java.classLoader.getResource("index.html")!!.readText(),
+ ContentType.Text.Html
+ )
+ }
+
+ static("/") {
+ resources("")
+ }
+
get("/people") {
- repository.fetchPeopleAsFlow().collect {
+ repository.fetchPeopleAsFlow()?.collect {
call.respond(it)
}
}
}
}.start(wait = true)
-}
\ No newline at end of file
+}
diff --git a/backend/src/main/resources/index.html b/backend/src/main/resources/index.html
new file mode 100644
index 0000000..2112171
--- /dev/null
+++ b/backend/src/main/resources/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+ People In Space
+
+
+People In Space
+
+
+
diff --git a/build.gradle.kts b/build.gradle.kts
index 5ff4c07..011305d 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -19,10 +19,8 @@ allprojects {
google()
mavenCentral()
jcenter()
+ maven("https://kotlin.bintray.com/kotlin-js-wrappers/")
}
}
-tasks.register("clean").configure {
- delete("build")
-}
diff --git a/common/build.gradle.kts b/common/build.gradle.kts
index 92f56ec..c784937 100644
--- a/common/build.gradle.kts
+++ b/common/build.gradle.kts
@@ -10,7 +10,6 @@ android {
compileSdkVersion(29)
buildToolsVersion("29.0.2")
-
defaultConfig {
minSdkVersion(21)
targetSdkVersion(29)
@@ -57,6 +56,11 @@ kotlin {
homepage = "Link to a Kotlin/Native module homepage"
}
+ js {
+ browser {
+ }
+ }
+
sourceSets {
val commonMain by getting {
dependencies {
@@ -123,9 +127,6 @@ kotlin {
// Ktor
implementation("io.ktor:ktor-server-core:${Versions.ktor}")
- implementation("io.ktor:ktor-server-netty:${Versions.ktor}")
- implementation("io.ktor:ktor-websockets:${Versions.ktor}")
- implementation("org.litote.kmongo:kmongo-coroutine-serialization:3.12.2")
implementation("io.ktor:ktor-client-core-jvm:${Versions.ktor}")
implementation("io.ktor:ktor-client-json-jvm:${Versions.ktor}")
@@ -206,6 +207,27 @@ kotlin {
implementation("com.squareup.sqldelight:runtime-macosx64:${Versions.sqlDelight}")
}
}
+
+ val jsMain by getting {
+ dependencies {
+ implementation(kotlin("stdlib-js"))
+
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:${Versions.kotlinCoroutines}")
+
+ // ktor
+ implementation("io.ktor:ktor-client-js:${Versions.ktor}") //include http&websockets
+ implementation("io.ktor:ktor-client-json-js:${Versions.ktor}")
+ implementation("io.ktor:ktor-client-logging-js:${Versions.ktor}")
+ implementation("io.ktor:ktor-client-serialization-js:${Versions.ktor}")
+
+ // Serialize
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:${Versions.kotlinxSerialization}")
+
+ // SQL Delight
+ //implementation("com.squareup.sqldelight:sqljs-driver:${Versions.sqlDelight}")
+ implementation("com.squareup.sqldelight:runtime-js:${Versions.sqlDelight}")
+ }
+ }
}
}
@@ -214,4 +236,5 @@ sqldelight {
packageName = "com.surrus.peopleinspace.db"
sourceFolders = listOf("sqldelight")
}
-}
\ No newline at end of file
+}
+
diff --git a/common/src/androidMain/kotlin/com/surrus/common/repository/actual.kt b/common/src/androidMain/kotlin/com/surrus/common/repository/actual.kt
index 41c2a36..d5556a1 100644
--- a/common/src/androidMain/kotlin/com/surrus/common/repository/actual.kt
+++ b/common/src/androidMain/kotlin/com/surrus/common/repository/actual.kt
@@ -10,7 +10,7 @@ import kotlinx.coroutines.launch
lateinit var appContext: Context
-actual fun createDb(): PeopleInSpaceDatabase {
+actual fun createDb(): PeopleInSpaceDatabase? {
val driver = AndroidSqliteDriver(PeopleInSpaceDatabase.Schema, appContext, "peopleinspace.db")
return PeopleInSpaceDatabase(driver)
}
diff --git a/common/src/commonMain/kotlin/com/surrus/common/repository/PeopleInSpaceRepository.kt b/common/src/commonMain/kotlin/com/surrus/common/repository/PeopleInSpaceRepository.kt
index 424e858..b7c86ff 100644
--- a/common/src/commonMain/kotlin/com/surrus/common/repository/PeopleInSpaceRepository.kt
+++ b/common/src/commonMain/kotlin/com/surrus/common/repository/PeopleInSpaceRepository.kt
@@ -9,7 +9,7 @@ import com.surrus.peopleinspace.db.PeopleInSpaceDatabase
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collect
-expect fun createDb() : PeopleInSpaceDatabase
+expect fun createDb() : PeopleInSpaceDatabase?
// TEMP until following is resolved https://github.com/ktorio/ktor/issues/1622
expect fun ktorScope(block: suspend () -> Unit)
@@ -18,7 +18,7 @@ expect fun ktorScope(block: suspend () -> Unit)
class PeopleInSpaceRepository {
private val peopleInSpaceApi = PeopleInSpaceApi()
private val peopleInSpaceDatabase = createDb()
- private val peopleInSpaceQueries = peopleInSpaceDatabase.peopleInSpaceQueries
+ private val peopleInSpaceQueries = peopleInSpaceDatabase?.peopleInSpaceQueries
init {
ktorScope {
@@ -26,25 +26,25 @@ class PeopleInSpaceRepository {
}
}
- fun fetchPeopleAsFlow() = peopleInSpaceQueries.selectAll(mapper = { name, craft ->
+ fun fetchPeopleAsFlow() = peopleInSpaceQueries?.selectAll(mapper = { name, craft ->
Assignment(name = name, craft = craft)
- }).asFlow().mapToList()
+ })?.asFlow()?.mapToList()
private suspend fun fetchAndStorePeople() {
val result = peopleInSpaceApi.fetchPeople()
// this is very basic implementation for now that removes all existing rows
// in db and then inserts reults from api request
- peopleInSpaceQueries.deleteAll()
+ peopleInSpaceQueries?.deleteAll()
result.people.forEach {
- peopleInSpaceQueries.insertItem(it.name, it.craft)
+ peopleInSpaceQueries?.insertItem(it.name, it.craft)
}
}
// called from iOS/watchOS/macOS client
fun fetchPeople(success: (List) -> Unit) {
GlobalScope.launch(Dispatchers.Main) {
- fetchPeopleAsFlow().collect {
+ fetchPeopleAsFlow()?.collect {
success(it)
}
}
diff --git a/common/src/iOSMain/kotlin/com/surrus/common/repository/actual.kt b/common/src/iOSMain/kotlin/com/surrus/common/repository/actual.kt
index 674c0e9..eba034b 100644
--- a/common/src/iOSMain/kotlin/com/surrus/common/repository/actual.kt
+++ b/common/src/iOSMain/kotlin/com/surrus/common/repository/actual.kt
@@ -6,7 +6,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
-actual fun createDb(): PeopleInSpaceDatabase {
+actual fun createDb(): PeopleInSpaceDatabase? {
val driver = NativeSqliteDriver(PeopleInSpaceDatabase.Schema, "peopleinspace.db")
return PeopleInSpaceDatabase(driver)
}
diff --git a/common/src/jsMain/kotlin/com/surrus/common/repository/actual.kt b/common/src/jsMain/kotlin/com/surrus/common/repository/actual.kt
new file mode 100644
index 0000000..8afb557
--- /dev/null
+++ b/common/src/jsMain/kotlin/com/surrus/common/repository/actual.kt
@@ -0,0 +1,15 @@
+package com.surrus.common.repository
+
+import com.surrus.peopleinspace.db.PeopleInSpaceDatabase
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+
+
+actual fun createDb(): PeopleInSpaceDatabase? {
+ return null
+}
+
+actual fun ktorScope(block: suspend () -> Unit) {
+ GlobalScope.launch(Dispatchers.Main) { block() }
+}
diff --git a/common/src/jvmMain/kotlin/com/surrus/Main.kt b/common/src/jvmMain/kotlin/com/surrus/Main.kt
index 66d6db2..311ee12 100644
--- a/common/src/jvmMain/kotlin/com/surrus/Main.kt
+++ b/common/src/jvmMain/kotlin/com/surrus/Main.kt
@@ -7,12 +7,14 @@ import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.runBlocking
@InternalCoroutinesApi
-fun main() = runBlocking {
- val api = PeopleInSpaceApi()
- println(api.fetchPeople())
+fun main() {
+ runBlocking {
+ val api = PeopleInSpaceApi()
+ println(api.fetchPeople())
- val repository = PeopleInSpaceRepository()
- repository.fetchPeopleAsFlow().collect {
- println(it)
+ val repository = PeopleInSpaceRepository()
+ repository.fetchPeopleAsFlow()?.collect {
+ println(it)
+ }
}
}
\ No newline at end of file
diff --git a/common/src/jvmMain/kotlin/com/surrus/common/repository/actual.kt b/common/src/jvmMain/kotlin/com/surrus/common/repository/actual.kt
index e01d3e2..164ec04 100644
--- a/common/src/jvmMain/kotlin/com/surrus/common/repository/actual.kt
+++ b/common/src/jvmMain/kotlin/com/surrus/common/repository/actual.kt
@@ -4,7 +4,7 @@ import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver
import com.surrus.peopleinspace.db.PeopleInSpaceDatabase
-actual fun createDb(): PeopleInSpaceDatabase {
+actual fun createDb(): PeopleInSpaceDatabase? {
val driver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)
.also { PeopleInSpaceDatabase.Schema.create(it) }
return PeopleInSpaceDatabase(driver)
diff --git a/common/src/macOSMain/kotlin/com/surrus/common/repository/actual.kt b/common/src/macOSMain/kotlin/com/surrus/common/repository/actual.kt
index 30a86c3..289d7b9 100644
--- a/common/src/macOSMain/kotlin/com/surrus/common/repository/actual.kt
+++ b/common/src/macOSMain/kotlin/com/surrus/common/repository/actual.kt
@@ -3,7 +3,7 @@ package com.surrus.common.repository
import com.squareup.sqldelight.drivers.native.NativeSqliteDriver
import com.surrus.peopleinspace.db.PeopleInSpaceDatabase
-actual fun createDb(): PeopleInSpaceDatabase {
+actual fun createDb(): PeopleInSpaceDatabase? {
val driver = NativeSqliteDriver(PeopleInSpaceDatabase.Schema, "peopleinspace.db")
return PeopleInSpaceDatabase(driver)
}
diff --git a/common/src/watchMain/kotlin/com/surrus/common/repository/actual.kt b/common/src/watchMain/kotlin/com/surrus/common/repository/actual.kt
index 674c0e9..eba034b 100644
--- a/common/src/watchMain/kotlin/com/surrus/common/repository/actual.kt
+++ b/common/src/watchMain/kotlin/com/surrus/common/repository/actual.kt
@@ -6,7 +6,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
-actual fun createDb(): PeopleInSpaceDatabase {
+actual fun createDb(): PeopleInSpaceDatabase? {
val driver = NativeSqliteDriver(PeopleInSpaceDatabase.Schema, "peopleinspace.db")
return PeopleInSpaceDatabase(driver)
}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 31f8b1a..d087da3 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,3 +1,5 @@
+include(":web")
+include(":backend")
rootProject.name = "PeopleInSpace"
enableFeaturePreview("GRADLE_METADATA")
diff --git a/web/.gitignore b/web/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/web/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/web/build.gradle.kts b/web/build.gradle.kts
new file mode 100644
index 0000000..8794eaf
--- /dev/null
+++ b/web/build.gradle.kts
@@ -0,0 +1,29 @@
+plugins {
+ kotlin("js")
+ kotlin("plugin.serialization")
+}
+
+dependencies {
+ implementation(kotlin("stdlib-js"))
+
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.3.5")
+ implementation("org.jetbrains.kotlinx:kotlinx-html-js:0.7.1")
+ implementation(npm("text-encoding"))
+ implementation(npm("abort-controller"))
+ implementation(npm("bufferutil"))
+ implementation(npm("utf-8-validate"))
+ implementation(npm("fs"))
+
+ //React, React DOM + Wrappers (chapter 3)
+ implementation("org.jetbrains:kotlin-react:16.13.0-pre.93-kotlin-1.3.70")
+ implementation("org.jetbrains:kotlin-react-dom:16.13.0-pre.93-kotlin-1.3.70")
+ implementation(npm("react", "16.13.0"))
+ implementation(npm("react-dom", "16.13.0"))
+
+
+ implementation(project(":common"))
+}
+
+
+kotlin.target.browser { }
+
diff --git a/web/src/main/kotlin/App.kt b/web/src/main/kotlin/App.kt
new file mode 100644
index 0000000..4f18d5f
--- /dev/null
+++ b/web/src/main/kotlin/App.kt
@@ -0,0 +1,29 @@
+import com.surrus.common.remote.Assignment
+import com.surrus.common.remote.PeopleInSpaceApi
+import react.*
+import react.dom.*
+import kotlinx.coroutines.*
+
+val scope = MainScope()
+val api = PeopleInSpaceApi()
+
+val App = functionalComponent { _ ->
+ val (people, setPeople) = useState(emptyList())
+
+ useEffect(dependencies = listOf()) {
+ scope.launch {
+ setPeople(api.fetchPeople().people)
+ }
+ }
+
+ h1 {
+ +"People In Space"
+ }
+ ul {
+ people.forEach { item ->
+ li {
+ +"${item.name} (${item.craft})"
+ }
+ }
+ }
+}
diff --git a/web/src/main/kotlin/Main.kt b/web/src/main/kotlin/Main.kt
new file mode 100644
index 0000000..0371cc0
--- /dev/null
+++ b/web/src/main/kotlin/Main.kt
@@ -0,0 +1,9 @@
+import react.child
+import react.dom.render
+import kotlin.browser.document
+
+fun main() {
+ render(document.getElementById("root")) {
+ child(functionalComponent = App)
+ }
+}
\ No newline at end of file
diff --git a/web/src/main/resources/index.html b/web/src/main/resources/index.html
new file mode 100644
index 0000000..20eda5b
--- /dev/null
+++ b/web/src/main/resources/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+ People In Space
+
+
+
+
+
+