From 667b3f983a3a77865e4fb89c0cf531ce982904ac Mon Sep 17 00:00:00 2001 From: Robert Jaros Date: Mon, 18 Feb 2019 17:10:10 +0100 Subject: Make kvision-remote module independent of kvision itself. Change the default JSON serialization format of Date objects (plain long value). --- kvision-modules/kvision-remote/build.gradle | 34 ++++++++++- .../kvision-remote/package.json.d/project.info | 3 - .../kotlin/pl/treksoft/kvision/remote/CallAgent.kt | 6 +- .../pl/treksoft/kvision/remote/KVRemoteAgent.kt | 1 - .../pl/treksoft/kvision/remote/RemoteAgent.kt | 12 ++-- .../kotlin/pl/treksoft/kvision/remote/Security.kt | 1 - .../kotlin/pl/treksoft/kvision/remote/Utils.kt | 62 ++++++++++++++++++++ .../main/kotlin/pl/treksoft/kvision/types/Date.kt | 68 ++++++++++++++++++++++ 8 files changed, 171 insertions(+), 16 deletions(-) delete mode 100644 kvision-modules/kvision-remote/package.json.d/project.info create mode 100644 kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Utils.kt create mode 100644 kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/types/Date.kt (limited to 'kvision-modules/kvision-remote') diff --git a/kvision-modules/kvision-remote/build.gradle b/kvision-modules/kvision-remote/build.gradle index b99fb199..277cce18 100644 --- a/kvision-modules/kvision-remote/build.gradle +++ b/kvision-modules/kvision-remote/build.gradle @@ -1,5 +1,37 @@ -apply from: "../shared.gradle" +apply plugin: 'kotlin-platform-js' +apply plugin: 'kotlinx-serialization' + +task cleanLibs(type: Delete) { + delete 'build/js', 'build/libs' +} + +if (project.gradle.startParameter.taskNames.contains("jar")) { + compileKotlin2Js.dependsOn 'cleanLibs' +} + +jar { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE +} + +compileKotlin2Js { + kotlinOptions.metaInfo = true + kotlinOptions.outputFile = "$project.buildDir.path/js/${project.name}.js" + kotlinOptions.sourceMap = !production + kotlinOptions.moduleKind = 'umd' +} + +compileTestKotlin2Js { + kotlinOptions.metaInfo = true + kotlinOptions.outputFile = "$project.buildDir.path/js-tests/${project.name}-tests.js" + kotlinOptions.sourceMap = !production + kotlinOptions.moduleKind = 'umd' +} dependencies { expectedBy project(":kvision-modules:kvision-common-remote") + expectedBy project(":kvision-modules:kvision-common-types") + compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlinVersion" + compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" + compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion" + compile "pl.treksoft:jquery-kotlin:$jqueryKotlinVersion" } diff --git a/kvision-modules/kvision-remote/package.json.d/project.info b/kvision-modules/kvision-remote/package.json.d/project.info deleted file mode 100644 index cfee4b2f..00000000 --- a/kvision-modules/kvision-remote/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Remote module" -} diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/CallAgent.kt b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/CallAgent.kt index 686d955b..06dd1330 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/CallAgent.kt +++ b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/CallAgent.kt @@ -30,10 +30,10 @@ import kotlinx.serialization.stringify import pl.treksoft.jquery.JQueryAjaxSettings import pl.treksoft.jquery.JQueryXHR import pl.treksoft.jquery.jQuery -import pl.treksoft.kvision.utils.JSON -import pl.treksoft.kvision.utils.JSON.toObj -import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.remote.JSON.toObj import kotlin.js.Promise +import kotlin.js.then +import kotlin.js.undefined import kotlin.js.JSON as NativeJSON /** diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/KVRemoteAgent.kt b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/KVRemoteAgent.kt index bd53407e..6054592e 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/KVRemoteAgent.kt +++ b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/KVRemoteAgent.kt @@ -25,7 +25,6 @@ import kotlinx.coroutines.asDeferred import kotlinx.serialization.ImplicitReflectionSerializer import kotlinx.serialization.list import kotlinx.serialization.serializer -import pl.treksoft.kvision.utils.JSON import kotlin.js.js import kotlin.reflect.KClass import kotlin.js.JSON as NativeJSON diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt index cbb2978a..52c0f7c3 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt +++ b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt @@ -34,9 +34,7 @@ import kotlinx.serialization.internal.ShortSerializer import kotlinx.serialization.internal.StringSerializer import kotlinx.serialization.list import kotlinx.serialization.serializer -import pl.treksoft.kvision.types.DateSerializer -import pl.treksoft.kvision.types.toStringF -import pl.treksoft.kvision.utils.JSON +import pl.treksoft.kvision.types.JsonDateSerializer import kotlin.js.Date import kotlin.reflect.KClass @@ -64,7 +62,7 @@ interface RemoteAgent { JSON.plain.stringify(StringSerializer.list as KSerializer, value) value[0] is Date -> @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(DateSerializer.list as KSerializer, value) + JSON.plain.stringify(JsonDateSerializer.list as KSerializer, value) value[0] is Int -> @Suppress("UNCHECKED_CAST") JSON.plain.stringify(IntSerializer.list as KSerializer, value) @@ -115,7 +113,7 @@ interface RemoteAgent { is Enum<*> -> "\"$value\"" is String -> value is Char -> "\"$value\"" - is Date -> "\"${value.toStringF()}\"" + is Date -> "\"${value.getTime()}\"" else -> try { @Suppress("UNCHECKED_CAST") JSON.plain.stringify(kClass.serializer(), value) @@ -139,7 +137,7 @@ interface RemoteAgent { "Boolean" -> JSON.plain.parse(BooleanSerializer, value) as RET "BoxedChar" -> JSON.plain.parse(CharSerializer, value) as RET "Short" -> JSON.plain.parse(ShortSerializer, value) as RET - "Date" -> JSON.plain.parse(DateSerializer, value) as RET + "Date" -> JSON.plain.parse(JsonDateSerializer, value) as RET "Byte" -> JSON.plain.parse(ByteSerializer, value) as RET else -> throw NotStandardTypeException(jsType) } @@ -158,7 +156,7 @@ interface RemoteAgent { "Boolean" -> JSON.plain.parse(BooleanSerializer.list, value) as List "BoxedChar" -> JSON.plain.parse(CharSerializer.list, value) as List "Short" -> JSON.plain.parse(ShortSerializer.list, value) as List - "Date" -> JSON.plain.parse(DateSerializer.list, value) as List + "Date" -> JSON.plain.parse(JsonDateSerializer.list, value) as List "Byte" -> JSON.plain.parse(ByteSerializer.list, value) as List else -> throw NotStandardTypeException(jsType) } diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt index e96744a9..fd2b5cb0 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt +++ b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt @@ -23,7 +23,6 @@ package pl.treksoft.kvision.remote import kotlinx.coroutines.asDeferred import kotlinx.serialization.Serializable -import pl.treksoft.kvision.utils.obj /** * A security exception. diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Utils.kt b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Utils.kt new file mode 100644 index 00000000..273c2a65 --- /dev/null +++ b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Utils.kt @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017-present Robert Jaros + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package pl.treksoft.kvision.remote + +import kotlinx.serialization.SerializationStrategy +import kotlinx.serialization.context.SimpleModule +import kotlinx.serialization.json.Json +import pl.treksoft.kvision.types.JsonDateSerializer +import kotlin.js.Date + +/** + * JavaScript Object type + */ +external class Object + +/** + * Helper function for creating JavaScript objects. + */ +fun obj(init: dynamic.() -> Unit): dynamic { + return (Object()).apply(init) +} + +/** + * JSON utility functions + */ +object JSON { + + val plain = Json().apply { + install(SimpleModule(Date::class, JsonDateSerializer)) + } + + val nonstrict = Json(strictMode = false).apply { + install(SimpleModule(Date::class, JsonDateSerializer)) + } + + /** + * An extension function to convert Serializable object to JS dynamic object + * @param serializer a serializer for T + */ + fun T.toObj(serializer: SerializationStrategy): dynamic { + return kotlin.js.JSON.parse(plain.stringify(serializer, this)) + } +} diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/types/Date.kt b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/types/Date.kt new file mode 100644 index 00000000..8cab5348 --- /dev/null +++ b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/types/Date.kt @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017-present Robert Jaros + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package pl.treksoft.kvision.types + +import kotlinx.serialization.Decoder +import kotlinx.serialization.Encoder +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialDescriptor +import kotlinx.serialization.internal.SerialClassDescImpl +import kotlin.js.Date + +actual typealias Date = kotlin.js.Date + +/** + * JSON date serializer. + */ +object JsonDateSerializer : KSerializer { + override val descriptor: SerialDescriptor = SerialClassDescImpl("kotlin.js.Date") + + override fun deserialize(decoder: Decoder): Date { + return Date(decoder.decodeLong()) + } + + override fun serialize(encoder: Encoder, obj: Date) { + encoder.encodeLong(obj.getTime().toLong()) + } +} + +/** + * @suppress + * Not used in this module. + */ +actual val KV_DEFAULT_DATE_FORMAT = "" + +/** + * @suppress + * Not used in this module. + */ +actual fun String.toDateF(format: String): Date { + TODO("Unimplemented") +} + +/** + * @suppress + * Not used in this module. + */ +actual fun Date.toStringF(format: String): String { + TODO("Unimplemented") +} -- cgit