Skip to content

Commit bea8868

Browse files
committed
fix serialization in js by avoiding reflection
remove unneeded generic and inline functions
1 parent a48f408 commit bea8868

File tree

31 files changed

+257
-220
lines changed

31 files changed

+257
-220
lines changed

firebase-app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ tasks {
104104
into.createNewFile()
105105
into.writeText(from.readText()
106106
.replace("require('firebase-", "require('@teamhubapp/firebase-")
107-
.replace("require('kotlinx-serialization-kotlinx-serialization-runtime')", "require('@cachet/kotlinx-serialization-runtime')")
108-
)
107+
// .replace("require('kotlinx-serialization-kotlinx-serialization-runtime')", "require('@teamhub/kotlinx-serialization-runtime')")
108+
)
109109
}
110110
}
111111

firebase-app/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@teamhubapp/firebase-app",
3-
"version": "0.1.0-beta",
3+
"version": "0.1.0-beta4",
44
"description": "Wrapper around firebase for usage in Kotlin Multiplatform projects",
55
"main": "firebase-app.js",
66
"scripts": {
@@ -19,11 +19,11 @@
1919
"author": "teamhub.dev",
2020
"license": "Apache-2.0",
2121
"bugs": {
22-
"url": "https://github.com/TeamHubApp/firebase-kotlin-multiplatform-sdk/issues"
22+
"url": "https://github.com/TeamHubApp/firebase-kotlin-sdk/issues"
2323
},
24-
"homepage": "https://github.com/TeamHubApp/firebase-kotlin-multiplatform-sdk",
24+
"homepage": "https://github.com/TeamHubApp/firebase-kotlin-sdk",
2525
"dependencies": {
26-
"@teamhubapp/firebase-common": "0.1.0-beta",
26+
"@teamhubapp/firebase-common": "0.1.0-beta4",
2727
"firebase": "6.2.3",
2828
"kotlin": "1.3.70",
2929
"kotlinx-coroutines-core": "1.3.4"

firebase-auth/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ tasks {
9999
into.createNewFile()
100100
into.writeText(from.readText()
101101
.replace("require('firebase-", "require('@teamhubapp/firebase-")
102-
.replace("require('kotlinx-serialization-kotlinx-serialization-runtime')", "require('@cachet/kotlinx-serialization-runtime')")
103-
)
102+
// .replace("require('kotlinx-serialization-kotlinx-serialization-runtime')", "require('@teamhub/kotlinx-serialization-runtime')")
103+
)
104104
}
105105
}
106106

firebase-auth/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@teamhubapp/firebase-auth",
3-
"version": "0.1.0-beta",
3+
"version": "0.1.0-beta4",
44
"description": "Wrapper around firebase for usage in Kotlin Multiplatform projects",
55
"main": "firebase-auth.js",
66
"scripts": {
@@ -19,11 +19,11 @@
1919
"author": "teamhub.dev",
2020
"license": "Apache-2.0",
2121
"bugs": {
22-
"url": "https://github.com/TeamHubApp/firebase-kotlin-multiplatform-sdk/issues"
22+
"url": "https://github.com/TeamHubApp/firebase-kotlin-sdk/issues"
2323
},
24-
"homepage": "https://github.com/TeamHubApp/firebase-kotlin-multiplatform-sdk",
24+
"homepage": "https://github.com/TeamHubApp/firebase-kotlin-sdk",
2525
"dependencies": {
26-
"@teamhubapp/firebase-app": "0.1.0-beta",
26+
"@teamhubapp/firebase-app": "0.1.0-beta4",
2727
"firebase": "6.2.3",
2828
"kotlin": "1.3.70",
2929
"kotlinx-coroutines-core": "1.3.4"

firebase-common/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ tasks {
124124
into.createNewFile()
125125
into.writeText(from.readText()
126126
.replace("require('firebase-", "require('@teamhubapp/firebase-")
127-
.replace("require('kotlinx-serialization-kotlinx-serialization-runtime')", "require('@cachet/kotlinx-serialization-runtime')")
127+
// .replace("require('kotlinx-serialization-kotlinx-serialization-runtime')", "require('@teamhubapp/kotlinx-serialization-runtime')")
128128
)
129129
}
130130
}

firebase-common/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@teamhubapp/firebase-common",
3-
"version": "0.1.0-beta",
3+
"version": "0.1.0-beta6",
44
"description": "Wrapper around firebase for usage in Kotlin Multiplatform projects",
55
"main": "firebase-common.js",
66
"scripts": {
@@ -26,7 +26,7 @@
2626
"firebase": "6.2.3",
2727
"kotlin": "1.3.70",
2828
"kotlinx-coroutines-core": "1.3.4",
29-
"@cachet/kotlinx-serialization-runtime": "0.20.0"
29+
"kotlinx-serialization-kotlinx-serialization-runtime": "0.20.0"
3030
}
3131
}
3232

firebase-common/src/androidMain/kotlin/dev/teamhub/firebase/_encoders.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ actual fun FirebaseEncoder.structureEncoder(desc: SerialDescriptor, vararg typeP
1010
StructureKind.LIST -> mutableListOf<Any?>()
1111
.also { value = it }
1212
.let { FirebaseCompositeEncoder(positiveInfinity) { _, index, value -> it.add(index, value) } }
13-
StructureKind.MAP, StructureKind.CLASS, StructureKind.OBJECT -> mutableMapOf<Any?, Any?>()
13+
StructureKind.MAP -> mutableListOf<Any?>()
14+
.let { FirebaseCompositeEncoder(positiveInfinity, { value = it.chunked(2).associate { (k, v) -> k to v } }) { _, _, value -> it.add(value) } }
15+
StructureKind.CLASS, StructureKind.OBJECT -> mutableMapOf<Any?, Any?>()
1416
.also { value = it }
1517
.let { FirebaseCompositeEncoder(positiveInfinity) { _, index, value -> it[desc.getElementName(index)] = value } }
1618
}
Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,36 @@
11
package dev.teamhub.firebase
22

33
import kotlinx.serialization.Serializable
4+
import kotlinx.serialization.builtins.ListSerializer
45
import kotlinx.serialization.serializer
56
import kotlin.test.Test
67
import kotlin.test.assertEquals
78

89
@Serializable
9-
data class TestData(val map: Map<String, String>)
10+
data class TestData(val map: Map<String, String>, val bool: Boolean = false)
1011

1112
class EncodersTest {
1213
@Test
1314
fun `encode a map`() {
14-
val encoded = encode<TestData>(TestData::class.serializer(), TestData(mapOf("key" to "value")))
15-
assertEquals(mapOf("map" to mapOf("key" to "value")), encoded)
15+
val encoded = encode(mapOf("key" to "value"))
16+
assertEquals(mapOf("key" to "value"), encoded)
1617
}
1718

1819
@Test
19-
fun `decode a map`() {
20+
fun `encode a class`() {
21+
val encoded = encode<TestData>(TestData::class.serializer(), TestData(mapOf("key" to "value"), true))
22+
assertEquals(mapOf("map" to mapOf("key" to "value"), "bool" to true), encoded)
23+
}
24+
25+
@Test
26+
fun `decode a class`() {
2027
val decoded = decode<TestData>(TestData::class.serializer(), mapOf("map" to mapOf("key" to "value")))
21-
assertEquals(TestData(mapOf("key" to "value")), decoded)
22-
}}
28+
assertEquals(TestData(mapOf("key" to "value"), false), decoded)
29+
}
30+
31+
@Test
32+
fun `decode a list of class`() {
33+
val decoded = decode(ListSerializer(TestData::class.serializer()), listOf(mapOf("map" to mapOf("key" to "value"))))
34+
assertEquals(listOf(TestData(mapOf("key" to "value"), false)), decoded)
35+
}
36+
}

firebase-common/src/commonMain/kotlin/dev/teamhub/firebase/decoders.kt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,20 @@ package dev.teamhub.firebase
33
import kotlinx.serialization.*
44
import kotlinx.serialization.CompositeDecoder.Companion.READ_DONE
55
import kotlinx.serialization.builtins.nullable
6-
import kotlinx.serialization.internal.UnitDescriptor
76
import kotlinx.serialization.modules.EmptyModule
87
import kotlinx.serialization.modules.SerialModule
98
import kotlinx.serialization.modules.getContextualOrDefault
109
import kotlin.reflect.KClass
1110

11+
@ImplicitReflectionSerializer
1212
@Suppress("UNCHECKED_CAST")
13-
inline fun <reified T> decode(strategy: DeserializationStrategy<T> = EmptyModule.getContextualOrDefault(T::class as KClass<Any>).run { if(null is T) nullable else this } as DeserializationStrategy<T>, value: Any?): T {
14-
require(value != null || strategy.descriptor.isNullable) { "Value was null for non-nullable type ${T::class}" }
13+
inline fun <reified T> decode(value: Any?): T {
14+
val strategy = EmptyModule.getContextualOrDefault(T::class as KClass<*>).run { if (null is T) nullable else this }
15+
return decode(strategy as DeserializationStrategy<T>, value)
16+
}
17+
18+
fun <T> decode(strategy: DeserializationStrategy<T>, value: Any?): T {
19+
require(value != null || strategy.descriptor.isNullable) { "Value was null for non-nullable type ${strategy.descriptor.serialName}" }
1520
return FirebaseDecoder(value).decode(strategy)
1621
}
1722

@@ -62,6 +67,8 @@ class FirebaseClassDecoder(
6267
) : FirebaseCompositeDecoder(size, get) {
6368
private var index: Int = 0
6469

70+
override fun decodeSequentially() = false
71+
6572
override fun decodeElementIndex(desc: SerialDescriptor): Int =
6673
(index until desc.elementsCount)
6774
.firstOrNull { !desc.isElementOptional(it) || containsKey(desc.getElementName(it)) }
@@ -89,9 +96,9 @@ open class FirebaseCompositeDecoder constructor(
8996
override fun <T : Any> decodeNullableSerializableElement(desc: SerialDescriptor, index: Int, deserializer: DeserializationStrategy<T?>): T? =
9097
if(decodeNotNullMark(get(desc, index))) decodeSerializableElement(desc, index, deserializer) else decodeNull(get(desc, index))
9198

92-
fun decodeNullableSerializableElement(index: Int): Any? = get(UnitDescriptor, index)?.let { value ->
93-
value.firebaseSerializer().let { decodeSerializableElement(it.descriptor, index, it) }
94-
}
99+
// fun decodeNullableSerializableElement(index: Int): Any? = get(UnitDescriptor, index)?.let { value ->
100+
// value.firebaseSerializer().let { decodeSerializableElement<Any>(it.descriptor, index, it) }
101+
// }
95102

96103
override fun <T> updateSerializableElement(desc: SerialDescriptor, index: Int, deserializer: DeserializationStrategy<T>, old: T): T =
97104
deserializer.deserialize(FirebaseDecoder(get(desc, index)))

firebase-common/src/commonMain/kotlin/dev/teamhub/firebase/encoders.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,25 +84,25 @@ abstract class TimestampEncoder(internal val positiveInfinity: Any) {
8484

8585
open class FirebaseCompositeEncoder constructor(
8686
positiveInfinity: Any,
87+
private val end: () -> Unit = {},
8788
private val set: (desc: SerialDescriptor, index: Int, value: Any?) -> Unit
8889
): TimestampEncoder(positiveInfinity), CompositeEncoder {
8990

9091
override val context = EmptyModule
9192

92-
private fun <T> SerializationStrategy<T>.toFirebase(): SerializationStrategy<T> = when(this.descriptor.kind) {
93-
StructureKind.MAP -> FirebaseMapSerializer() as SerializationStrategy<T>
94-
StructureKind.LIST -> FirebaseListSerializer() as SerializationStrategy<T>
95-
else -> this
96-
}
93+
// private fun <T> SerializationStrategy<T>.toFirebase(): SerializationStrategy<T> = when(descriptor.kind) {
94+
// StructureKind.MAP -> FirebaseMapSerializer<Any>(descriptor.getElementDescriptor(1)) as SerializationStrategy<T>
95+
// StructureKind.LIST -> FirebaseListSerializer<Any>(descriptor.getElementDescriptor(0)) as SerializationStrategy<T>
96+
// else -> this
97+
// }
9798

98-
override fun endStructure(descriptor: SerialDescriptor) {
99-
}
99+
override fun endStructure(descriptor: SerialDescriptor) = end()
100100

101101
override fun <T : Any> encodeNullableSerializableElement(desc: SerialDescriptor, index: Int, serializer: SerializationStrategy<T>, value: T?) =
102-
set(desc, index, value?.let { FirebaseEncoder(positiveInfinity).apply { encode(serializer.toFirebase(), value) }.value })
102+
set(desc, index, value?.let { FirebaseEncoder(positiveInfinity).apply { encode(serializer, value) }.value })
103103

104104
override fun <T> encodeSerializableElement(desc: SerialDescriptor, index: Int, serializer: SerializationStrategy<T>, value: T) =
105-
set(desc, index, FirebaseEncoder(positiveInfinity).apply { encode(serializer.toFirebase(), value) }.value)
105+
set(desc, index, FirebaseEncoder(positiveInfinity).apply { encode(serializer, value) }.value)
106106

107107
override fun encodeNonSerializableElement(desc: SerialDescriptor, index: Int, value: Any) = set(desc, index, value)
108108

0 commit comments

Comments
 (0)