From 8f4cb5916549c7214d9993a0ec7ce533c273e72c Mon Sep 17 00:00:00 2001 From: Michael Rittmeister Date: Sat, 2 Nov 2024 18:48:08 +0100 Subject: [PATCH 1/6] Initial Zstd draft --- .../kotlin/builder/kord/KordBuilder.kt | 7 + gateway/build.gradle.kts | 2 + gateway/src/commonMain/kotlin/Compression.kt | 54 +++++++ .../src/commonMain/kotlin/DefaultGateway.kt | 37 +++-- .../kotlin/DefaultGatewayBuilder.kt | 6 +- gateway/src/commonMain/kotlin/Inflater.kt | 9 -- .../{Inflater.kt => ZLibDecompressor.kt} | 4 +- gateway/src/jsMain/kotlin/ZstdDecompressor.kt | 29 ++++ gateway/src/jsMain/kotlin/internal/JsZstd.kt | 7 + .../{Inflater.kt => ZLibDecompressor.kt} | 4 +- .../src/jvmMain/kotlin/ZstdDecompressor.kt | 33 ++++ gradle/libs.versions.toml | 3 + kotlin-js-store/yarn.lock | 150 +++++++++++++++++- .../resources/simplelogger.properties | 2 + 14 files changed, 312 insertions(+), 35 deletions(-) create mode 100644 gateway/src/commonMain/kotlin/Compression.kt delete mode 100644 gateway/src/commonMain/kotlin/Inflater.kt rename gateway/src/jsMain/kotlin/{Inflater.kt => ZLibDecompressor.kt} (76%) create mode 100644 gateway/src/jsMain/kotlin/ZstdDecompressor.kt create mode 100644 gateway/src/jsMain/kotlin/internal/JsZstd.kt rename gateway/src/jvmMain/kotlin/{Inflater.kt => ZLibDecompressor.kt} (80%) create mode 100644 gateway/src/jvmMain/kotlin/ZstdDecompressor.kt create mode 100644 samples/src/commonMain/resources/simplelogger.properties diff --git a/core/src/commonMain/kotlin/builder/kord/KordBuilder.kt b/core/src/commonMain/kotlin/builder/kord/KordBuilder.kt index 04272a75633..a1909c90164 100644 --- a/core/src/commonMain/kotlin/builder/kord/KordBuilder.kt +++ b/core/src/commonMain/kotlin/builder/kord/KordBuilder.kt @@ -15,6 +15,7 @@ import dev.kord.core.gateway.DefaultMasterGateway import dev.kord.core.gateway.handler.DefaultGatewayEventInterceptor import dev.kord.core.gateway.handler.GatewayEventInterceptor import dev.kord.core.supplier.EntitySupplyStrategy +import dev.kord.gateway.Compression import dev.kord.gateway.DefaultGateway import dev.kord.gateway.Gateway import dev.kord.gateway.builder.Shards @@ -49,6 +50,7 @@ public abstract class BaseKordBuilder internal constructor(public val token: Str DefaultGateway { client = resources.httpClient identifyRateLimiter = rateLimiter + compression = this@BaseKordBuilder.compression } } } @@ -57,6 +59,11 @@ public abstract class BaseKordBuilder internal constructor(public val token: Str { KtorRequestHandler(it.httpClient, ExclusionRequestRateLimiter(), token = token) } private var cacheBuilder: KordCacheBuilder.(resources: ClientResources) -> Unit = {} + /** + * The [compression mode][Compression] used. + */ + public var compression: Compression = Compression.ZLib + /** * Enables stack trace recovery on the currently defined [RequestHandler]. * diff --git a/gateway/build.gradle.kts b/gateway/build.gradle.kts index 2b646a41100..c27010edd18 100644 --- a/gateway/build.gradle.kts +++ b/gateway/build.gradle.kts @@ -19,12 +19,14 @@ kotlin { jvmMain { dependencies { implementation(libs.slf4j.api) + implementation(libs.zstd.jni) } } jsMain { dependencies { implementation(libs.kotlin.node) implementation(npm("fast-zlib", libs.versions.fastZlib.get())) + implementation(npm("simple-zstd", "1.4.2")) // workaround for https://youtrack.jetbrains.com/issue/KT-43500 / // https://youtrack.jetbrains.com/issue/KT-64109#focus=Comments-27-10064206.0-0 / diff --git a/gateway/src/commonMain/kotlin/Compression.kt b/gateway/src/commonMain/kotlin/Compression.kt new file mode 100644 index 00000000000..598637c4c6f --- /dev/null +++ b/gateway/src/commonMain/kotlin/Compression.kt @@ -0,0 +1,54 @@ +@file:Suppress("FunctionName") + +package dev.kord.gateway + +import dev.kord.common.annotation.KordInternal +import io.ktor.websocket.* + +/** @suppress */ +@KordInternal // Only public for interface, binary API might change at any time +public interface Decompressor : AutoCloseable { + public fun Frame.decompress(): String + + public companion object Noop : Decompressor { + override fun Frame.decompress(): String = data.decodeToString() + override fun close() {} + } +} + +internal expect fun ZLibDecompressor(): Decompressor +internal expect fun ZstdDecompressor(): Decompressor + +/** + * Different compression modes for the Discord gateway. + * + * @property name the name used by the Discord API + */ +public sealed interface Compression { + public val name: String? + public fun newDecompressor(): Decompressor + + /** + * Implementation using no compression. + */ + public data object None : Compression { + override val name: String? = null + override fun newDecompressor(): Decompressor = Decompressor.Noop + } + + /** + * Implementation using [zlib](https://zlib.net/). + */ + public data object ZLib : Compression { + override val name: String = "zlib-stream" + override fun newDecompressor(): Decompressor = ZLibDecompressor() + } + + /** + * Implementation using [Zstandard](https://facebook.github.io/zstd/) + */ + public data object Zstd : Compression { + override val name: String = "zstd-stream" + override fun newDecompressor(): Decompressor = ZstdDecompressor() + } +} diff --git a/gateway/src/commonMain/kotlin/DefaultGateway.kt b/gateway/src/commonMain/kotlin/DefaultGateway.kt index 8a5f673ffc0..5847a68a4f9 100644 --- a/gateway/src/commonMain/kotlin/DefaultGateway.kt +++ b/gateway/src/commonMain/kotlin/DefaultGateway.kt @@ -39,12 +39,13 @@ private sealed class State(val retry: Boolean) { } /** - * @param url The url to connect to. - * @param client The [HttpClient] from which a WebSocket will be created, requires the [WebSockets] plugin to be + * @property url The url to connect to. + * @property client The [HttpClient] from which a WebSocket will be created, requires the [WebSockets] plugin to be * installed. - * @param reconnectRetry A [Retry] used for reconnection attempts. - * @param sendRateLimiter A [RateLimiter] that follows the Discord API specifications for sending messages. - * @param identifyRateLimiter An [IdentifyRateLimiter] that follows the Discord API specifications for identifying. + * @property reconnectRetry A [Retry] used for reconnection attempts. + * @property sendRateLimiter A [RateLimiter] that follows the Discord API specifications for sending messages. + * @property identifyRateLimiter An [IdentifyRateLimiter] that follows the Discord API specifications for identifying. + * @property compression the [compression mode][Compression] used */ public data class DefaultGatewayData( val url: String, @@ -54,6 +55,7 @@ public data class DefaultGatewayData( val identifyRateLimiter: IdentifyRateLimiter, val dispatcher: CoroutineDispatcher, val eventFlow: MutableSharedFlow, + val compression: Compression, ) /** @@ -63,8 +65,6 @@ public class DefaultGateway(private val data: DefaultGatewayData) : Gateway { override val coroutineContext: CoroutineContext = SupervisorJob() + data.dispatcher - private val compression: Boolean - private val _ping = MutableStateFlow(null) override val ping: StateFlow get() = _ping @@ -76,7 +76,7 @@ public class DefaultGateway(private val data: DefaultGatewayData) : Gateway { private val handshakeHandler: HandshakeHandler - private lateinit var inflater: Inflater + private lateinit var decompressor: Decompressor private val jsonParser = Json { ignoreUnknownKeys = true @@ -86,9 +86,10 @@ public class DefaultGateway(private val data: DefaultGatewayData) : Gateway { private val stateMutex = Mutex() init { - val initialUrl = Url(data.url) - compression = initialUrl.parameters.contains("compress", "zlib-stream") - + val initialUrl = URLBuilder(data.url).apply { + val compressionName = data.compression.name ?: return@apply + parameters.append("compress", compressionName) + }.build() val sequence = Sequence() SequenceHandler(events, sequence) handshakeHandler = HandshakeHandler(events, initialUrl, ::trySend, sequence, data.reconnectRetry) @@ -117,7 +118,11 @@ public class DefaultGateway(private val data: DefaultGatewayData) : Gateway { * * > Every connection to the gateway should use its own unique zlib context. */ - inflater = Inflater() + try { + decompressor = data.compression.newDecompressor() + } catch (e: Throwable) { + e.printStackTrace() + } } catch (exception: Exception) { defaultGatewayLogger.error(exception) { "" } if (exception.isTimeout()) { @@ -179,10 +184,7 @@ public class DefaultGateway(private val data: DefaultGatewayData) : Gateway { private suspend fun read(frame: Frame) { defaultGatewayLogger.trace { "Received raw frame: $frame" } - val json = when { - compression -> with(inflater) { frame.inflateData() } - else -> frame.data.decodeToString() - } + val json = with(decompressor) { frame.decompress() } try { defaultGatewayLogger.trace { "Gateway <<< $json" } @@ -195,7 +197,7 @@ public class DefaultGateway(private val data: DefaultGatewayData) : Gateway { } private suspend fun handleClose() { - inflater.close() + decompressor.close() val reason = withTimeoutOrNull(1500) { socket.closeReason.await() @@ -211,6 +213,7 @@ public class DefaultGateway(private val data: DefaultGatewayData) : Gateway { state.update { State.Stopped } throw IllegalStateException("Gateway closed: ${reason.code} ${reason.message}") } + discordReason.resetSession -> { setStopped() } diff --git a/gateway/src/commonMain/kotlin/DefaultGatewayBuilder.kt b/gateway/src/commonMain/kotlin/DefaultGatewayBuilder.kt index 7dd8febc9cc..cf840cb4ddb 100644 --- a/gateway/src/commonMain/kotlin/DefaultGatewayBuilder.kt +++ b/gateway/src/commonMain/kotlin/DefaultGatewayBuilder.kt @@ -18,13 +18,14 @@ import kotlin.time.Duration.Companion.seconds public class DefaultGatewayBuilder { public var url: String = - "wss://gateway.discord.gg/?v=${KordConfiguration.GATEWAY_VERSION}&encoding=json&compress=zlib-stream" + "wss://gateway.discord.gg/?v=${KordConfiguration.GATEWAY_VERSION}&encoding=json" public var client: HttpClient? = null public var reconnectRetry: Retry? = null public var sendRateLimiter: RateLimiter? = null public var identifyRateLimiter: IdentifyRateLimiter? = null public var dispatcher: CoroutineDispatcher = Dispatchers.Default public var eventFlow: MutableSharedFlow = MutableSharedFlow(extraBufferCapacity = Int.MAX_VALUE) + public var compression: Compression = Compression.ZLib public fun build(): DefaultGateway { val client = client ?: HttpClient(httpEngine()) { @@ -44,7 +45,8 @@ public class DefaultGatewayBuilder { sendRateLimiter, identifyRateLimiter, dispatcher, - eventFlow + eventFlow, + compression ) return DefaultGateway(data) diff --git a/gateway/src/commonMain/kotlin/Inflater.kt b/gateway/src/commonMain/kotlin/Inflater.kt deleted file mode 100644 index d8078372c4c..00000000000 --- a/gateway/src/commonMain/kotlin/Inflater.kt +++ /dev/null @@ -1,9 +0,0 @@ -package dev.kord.gateway - -import io.ktor.websocket.* - -internal interface Inflater : AutoCloseable { - fun Frame.inflateData(): String -} - -internal expect fun Inflater(): Inflater diff --git a/gateway/src/jsMain/kotlin/Inflater.kt b/gateway/src/jsMain/kotlin/ZLibDecompressor.kt similarity index 76% rename from gateway/src/jsMain/kotlin/Inflater.kt rename to gateway/src/jsMain/kotlin/ZLibDecompressor.kt index 418c269d094..28dd1a67017 100644 --- a/gateway/src/jsMain/kotlin/Inflater.kt +++ b/gateway/src/jsMain/kotlin/ZLibDecompressor.kt @@ -5,10 +5,10 @@ import io.ktor.websocket.* import node.buffer.Buffer import node.buffer.BufferEncoding -internal actual fun Inflater() = object : Inflater { +internal actual fun ZLibDecompressor() = object : Decompressor { private val inflate = Inflate() - override fun Frame.inflateData(): String { + override fun Frame.decompress(): String { val buffer = Buffer.from(data) return inflate.process(buffer).toString(BufferEncoding.utf8) diff --git a/gateway/src/jsMain/kotlin/ZstdDecompressor.kt b/gateway/src/jsMain/kotlin/ZstdDecompressor.kt new file mode 100644 index 00000000000..fe36455df64 --- /dev/null +++ b/gateway/src/jsMain/kotlin/ZstdDecompressor.kt @@ -0,0 +1,29 @@ +package dev.kord.gateway + +import dev.kord.gateway.internal.ZSTDDecompress +import io.ktor.websocket.* +import js.typedarrays.toUint8Array +import node.stream.DuplexEvent +import web.encoding.TextDecoder + +internal actual fun ZstdDecompressor() = object : Decompressor { + private val stream = ZSTDDecompress() + private val decoder = TextDecoder() + + override fun Frame.decompress(): String { + try { + stream.write(data.toUint8Array()) + stream.on(DuplexEvent.FINISH) { + println("finish") + } + stream.on(DuplexEvent.DATA) { + println("Data: $it") + } + } catch (exception: Exception) { + exception.printStackTrace() + } + return "" + } + + override fun close() = stream.end() +} diff --git a/gateway/src/jsMain/kotlin/internal/JsZstd.kt b/gateway/src/jsMain/kotlin/internal/JsZstd.kt new file mode 100644 index 00000000000..e9bc8bdef87 --- /dev/null +++ b/gateway/src/jsMain/kotlin/internal/JsZstd.kt @@ -0,0 +1,7 @@ +@file:JsModule("simple-zstd") + +package dev.kord.gateway.internal + +import node.stream.Transform + +internal external class ZSTDDecompress : Transform diff --git a/gateway/src/jvmMain/kotlin/Inflater.kt b/gateway/src/jvmMain/kotlin/ZLibDecompressor.kt similarity index 80% rename from gateway/src/jvmMain/kotlin/Inflater.kt rename to gateway/src/jvmMain/kotlin/ZLibDecompressor.kt index 348ba9ae389..14aba474830 100644 --- a/gateway/src/jvmMain/kotlin/Inflater.kt +++ b/gateway/src/jvmMain/kotlin/ZLibDecompressor.kt @@ -4,10 +4,10 @@ import io.ktor.websocket.* import java.io.ByteArrayOutputStream import java.util.zip.InflaterOutputStream -internal actual fun Inflater() = object : Inflater { +internal actual fun ZLibDecompressor() = object : Decompressor { private val delegate = java.util.zip.Inflater() - override fun Frame.inflateData(): String { + override fun Frame.decompress(): String { val outputStream = ByteArrayOutputStream() InflaterOutputStream(outputStream, delegate).use { it.write(data) diff --git a/gateway/src/jvmMain/kotlin/ZstdDecompressor.kt b/gateway/src/jvmMain/kotlin/ZstdDecompressor.kt new file mode 100644 index 00000000000..49d45b281cd --- /dev/null +++ b/gateway/src/jvmMain/kotlin/ZstdDecompressor.kt @@ -0,0 +1,33 @@ +package dev.kord.gateway + +import com.github.luben.zstd.ZstdInputStream +import io.ktor.websocket.* +import java.io.ByteArrayInputStream +import java.io.InputStream + +internal actual fun ZstdDecompressor() = object : Decompressor { + + private val input = UpdatableByteArrayInputStream() + private val zstdStream = ZstdInputStream(input).apply { continuous = true } + + override fun Frame.decompress(): String { + input.updateDelegate(data) + return zstdStream.readAllBytes().decodeToString() + } + + override fun close() { + zstdStream.close() + } +} + +private class UpdatableByteArrayInputStream : InputStream() { + private var delegate: ByteArrayInputStream? = null + + private val d: InputStream get() = delegate ?: error("No data available") + + override fun read(): Int = d.read() + + fun updateDelegate(bytes: ByteArray) { + delegate = ByteArrayInputStream(bytes) + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1599989c8fa..c6b2732ac51 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,8 @@ kotlin-node = "22.5.4-pre.818" # https://github.com/JetBrains/kotlin-wrappers bignum = "0.3.10" # https://github.com/ionspin/kotlin-multiplatform-bignum stately = "2.1.0" # https://github.com/touchlab/Stately fastZlib = "2.0.1" # https://github.com/timotejroiko/fast-zlib +zstd-jni = "1.5.6-7" # https://github.com/luben/zstd-jni +zstd-codec = "0.1.5" # https://www.npmjs.com/package/zstd-codec # code generation ksp = "2.0.21-1.0.25" # https://github.com/google/ksp @@ -63,6 +65,7 @@ kotlin-node = { module = "org.jetbrains.kotlin-wrappers:kotlin-node", version.re # JDK replacements bignum = { module = "com.ionspin.kotlin:bignum", version.ref = "bignum" } stately-collections = { module = "co.touchlab:stately-concurrent-collections", version.ref = "stately" } +zstd-jni = { module = "com.github.luben:zstd-jni", version.ref = "zstd-jni" } # code generation ksp-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" } diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index 493392acc4e..dc20ca6dd7c 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -127,6 +127,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + debug@^4.3.5: version "4.3.6" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" @@ -144,11 +149,33 @@ diff@^5.2.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== +duplex-maker@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/duplex-maker/-/duplex-maker-1.0.0.tgz#1604f8b943cb0063a6d3e1fe42aa65113a79da4a" + integrity sha512-KoHuzggxg7f+vvjqOHfXxaQYI1POzBm+ah0eec7YDssZmbt6QFBI8d1nl5GQwAgR2f+VQCPvyvZtmWWqWuFtlA== + +duplexify@^3.5.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +end-of-stream@^1.0.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -245,7 +272,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -289,6 +316,16 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-zst@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-zst/-/is-zst-1.0.0.tgz#97462bb1a376dabba561e249ea754801e9b90fe0" + integrity sha512-ZA5lvshKAl8z30dX7saXLpVhpsq3d2EHK9uf7qtUjnOtdw4XBpAoWb2RvZ5kyoaebdoidnGI0g2hn9Z7ObPbww== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" @@ -366,7 +403,7 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -once@^1.3.0: +once@^1.3.0, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -392,11 +429,32 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +peek-stream@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/peek-stream/-/peek-stream-1.1.3.tgz#3b35d84b7ccbbd262fff31dc10da56856ead6d67" + integrity sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA== + dependencies: + buffer-from "^1.0.0" + duplexify "^3.5.0" + through2 "^2.0.3" + picomatch@^2.0.4, picomatch@^2.2.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process-streams@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/process-streams/-/process-streams-1.0.3.tgz#8df3e807932fc80cbb2ab92dd7c6f199c5faa9b1" + integrity sha512-xkIaM5vYnyekB88WyET78YEqXiaJRy0xcvIdE22n+myhvBT7LlLmX6iAtq7jDvVH8CUx2rqQsd32JdRyJMV3NA== + dependencies: + duplex-maker "^1.0.0" + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -404,6 +462,28 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" +readable-stream@3: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@^2.0.0, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -416,11 +496,16 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== -safe-buffer@^5.1.0: +safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + serialize-javascript@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" @@ -428,6 +513,16 @@ serialize-javascript@^6.0.2: dependencies: randombytes "^2.1.0" +simple-zstd@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/simple-zstd/-/simple-zstd-1.4.2.tgz#4f5b7b05dfd2930b03092eb0c0cd13a44bad4b34" + integrity sha512-kGYEvT33M5XfyQvvW4wxl3eKcWbdbCc1V7OZzuElnaXft0qbVzoIIXHXiCm3JCUki+MZKKmvjl8p2VGLJc5Y/A== + dependencies: + is-zst "^1.0.0" + peek-stream "^1.1.3" + process-streams "^1.0.1" + through2 "^4.0.2" + source-map-support@0.5.21: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" @@ -441,6 +536,11 @@ source-map@^0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +stream-shift@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" + integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== + string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -450,6 +550,20 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -476,6 +590,21 @@ supports-color@^8.1.1: dependencies: has-flag "^4.0.0" +through2@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through2@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" + integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== + dependencies: + readable-stream "3" + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -493,6 +622,11 @@ typescript@5.5.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -530,6 +664,11 @@ ws@8.5.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== +xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -567,3 +706,8 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zstd-codec@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/zstd-codec/-/zstd-codec-0.1.5.tgz#c180193e4603ef74ddf704bcc835397d30a60e42" + integrity sha512-v3fyjpK8S/dpY/X5WxqTK3IoCnp/ZOLxn144GZVlNUjtwAchzrVo03h+oMATFhCIiJ5KTr4V3vDQQYz4RU684g== diff --git a/samples/src/commonMain/resources/simplelogger.properties b/samples/src/commonMain/resources/simplelogger.properties new file mode 100644 index 00000000000..b4378621551 --- /dev/null +++ b/samples/src/commonMain/resources/simplelogger.properties @@ -0,0 +1,2 @@ +org.slf4j.simpleLogger.defaultLogLevel=trace +org.slf4j.simpleLogger.showDateTime=true \ No newline at end of file From b052fdbe86f35663a384b027841e0a9d6bfcf289 Mon Sep 17 00:00:00 2001 From: Michael Rittmeister Date: Wed, 6 Nov 2024 17:26:57 +0100 Subject: [PATCH 2/6] Add js implementation --- gateway/build.gradle.kts | 2 +- gateway/src/jsMain/kotlin/ZstdDecompressor.kt | 26 +-- gateway/src/jsMain/kotlin/internal/JsZstd.kt | 10 +- gradle/libs.versions.toml | 1 + kotlin-js-store/yarn.lock | 155 +----------------- 5 files changed, 26 insertions(+), 168 deletions(-) diff --git a/gateway/build.gradle.kts b/gateway/build.gradle.kts index c27010edd18..1452fe924ea 100644 --- a/gateway/build.gradle.kts +++ b/gateway/build.gradle.kts @@ -26,7 +26,7 @@ kotlin { dependencies { implementation(libs.kotlin.node) implementation(npm("fast-zlib", libs.versions.fastZlib.get())) - implementation(npm("simple-zstd", "1.4.2")) + implementation(npm("fzstd", libs.versions.fzstd.get())) // workaround for https://youtrack.jetbrains.com/issue/KT-43500 / // https://youtrack.jetbrains.com/issue/KT-64109#focus=Comments-27-10064206.0-0 / diff --git a/gateway/src/jsMain/kotlin/ZstdDecompressor.kt b/gateway/src/jsMain/kotlin/ZstdDecompressor.kt index fe36455df64..ad944552b71 100644 --- a/gateway/src/jsMain/kotlin/ZstdDecompressor.kt +++ b/gateway/src/jsMain/kotlin/ZstdDecompressor.kt @@ -1,29 +1,21 @@ package dev.kord.gateway -import dev.kord.gateway.internal.ZSTDDecompress + import dev.kord.gateway.internal.Decompress import io.ktor.websocket.* import js.typedarrays.toUint8Array -import node.stream.DuplexEvent -import web.encoding.TextDecoder internal actual fun ZstdDecompressor() = object : Decompressor { - private val stream = ZSTDDecompress() - private val decoder = TextDecoder() + private val stream = Decompress() override fun Frame.decompress(): String { - try { - stream.write(data.toUint8Array()) - stream.on(DuplexEvent.FINISH) { - println("finish") - } - stream.on(DuplexEvent.DATA) { - println("Data: $it") - } - } catch (exception: Exception) { - exception.printStackTrace() + var cache = ByteArray(0) + stream.onData = { data, _ -> + cache += data.toByteArray() } - return "" + // This call is sync, so if it finishes, the cache will store all the chunks + stream.push(data.toUint8Array()) + return cache.decodeToString() } - override fun close() = stream.end() + override fun close() = Unit } diff --git a/gateway/src/jsMain/kotlin/internal/JsZstd.kt b/gateway/src/jsMain/kotlin/internal/JsZstd.kt index e9bc8bdef87..48f6bde336d 100644 --- a/gateway/src/jsMain/kotlin/internal/JsZstd.kt +++ b/gateway/src/jsMain/kotlin/internal/JsZstd.kt @@ -1,7 +1,11 @@ -@file:JsModule("simple-zstd") +@file:JsModule("fzstd") package dev.kord.gateway.internal -import node.stream.Transform +import js.typedarrays.Uint8Array -internal external class ZSTDDecompress : Transform +internal external class Decompress { + @JsName("ondata") + var onData: (data: Uint8Array, final: Boolean) -> Unit + fun push(chunk: Uint8Array, final: Boolean = definedExternally) +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c6b2732ac51..2b48bc43818 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ kotlin-node = "22.5.4-pre.818" # https://github.com/JetBrains/kotlin-wrappers bignum = "0.3.10" # https://github.com/ionspin/kotlin-multiplatform-bignum stately = "2.1.0" # https://github.com/touchlab/Stately fastZlib = "2.0.1" # https://github.com/timotejroiko/fast-zlib +fzstd = "0.1.1" # https://github.com/101arrowz/fzstd/ zstd-jni = "1.5.6-7" # https://github.com/luben/zstd-jni zstd-codec = "0.1.5" # https://www.npmjs.com/package/zstd-codec diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index dc20ca6dd7c..b33d9525e4c 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -127,11 +127,6 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - debug@^4.3.5: version "4.3.6" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" @@ -149,33 +144,11 @@ diff@^5.2.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== -duplex-maker@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/duplex-maker/-/duplex-maker-1.0.0.tgz#1604f8b943cb0063a6d3e1fe42aa65113a79da4a" - integrity sha512-KoHuzggxg7f+vvjqOHfXxaQYI1POzBm+ah0eec7YDssZmbt6QFBI8d1nl5GQwAgR2f+VQCPvyvZtmWWqWuFtlA== - -duplexify@^3.5.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -end-of-stream@^1.0.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -231,6 +204,11 @@ fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== +fzstd@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/fzstd/-/fzstd-0.1.1.tgz#a3da29f2fff45070ca90073f866d97e0c56a4a52" + integrity sha512-dkuVSOKKwh3eas5VkJy1AW1vFpet8TA/fGmVA5krThl8YcOVE/8ZIoEA1+U1vEn5ckxxhLirSdY837azmbaNHA== + get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -272,7 +250,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: +inherits@2: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -316,16 +294,6 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-zst@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-zst/-/is-zst-1.0.0.tgz#97462bb1a376dabba561e249ea754801e9b90fe0" - integrity sha512-ZA5lvshKAl8z30dX7saXLpVhpsq3d2EHK9uf7qtUjnOtdw4XBpAoWb2RvZ5kyoaebdoidnGI0g2hn9Z7ObPbww== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" @@ -403,7 +371,7 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -once@^1.3.0, once@^1.4.0: +once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -429,32 +397,11 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== -peek-stream@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/peek-stream/-/peek-stream-1.1.3.tgz#3b35d84b7ccbbd262fff31dc10da56856ead6d67" - integrity sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA== - dependencies: - buffer-from "^1.0.0" - duplexify "^3.5.0" - through2 "^2.0.3" - picomatch@^2.0.4, picomatch@^2.2.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -process-streams@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/process-streams/-/process-streams-1.0.3.tgz#8df3e807932fc80cbb2ab92dd7c6f199c5faa9b1" - integrity sha512-xkIaM5vYnyekB88WyET78YEqXiaJRy0xcvIdE22n+myhvBT7LlLmX6iAtq7jDvVH8CUx2rqQsd32JdRyJMV3NA== - dependencies: - duplex-maker "^1.0.0" - randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -462,28 +409,6 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -readable-stream@3: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^2.0.0, readable-stream@~2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -496,16 +421,11 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== -safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - serialize-javascript@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" @@ -513,16 +433,6 @@ serialize-javascript@^6.0.2: dependencies: randombytes "^2.1.0" -simple-zstd@1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/simple-zstd/-/simple-zstd-1.4.2.tgz#4f5b7b05dfd2930b03092eb0c0cd13a44bad4b34" - integrity sha512-kGYEvT33M5XfyQvvW4wxl3eKcWbdbCc1V7OZzuElnaXft0qbVzoIIXHXiCm3JCUki+MZKKmvjl8p2VGLJc5Y/A== - dependencies: - is-zst "^1.0.0" - peek-stream "^1.1.3" - process-streams "^1.0.1" - through2 "^4.0.2" - source-map-support@0.5.21: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" @@ -536,11 +446,6 @@ source-map@^0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -stream-shift@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" - integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== - string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -550,20 +455,6 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -590,21 +481,6 @@ supports-color@^8.1.1: dependencies: has-flag "^4.0.0" -through2@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through2@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" - integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== - dependencies: - readable-stream "3" - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -622,11 +498,6 @@ typescript@5.5.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -664,11 +535,6 @@ ws@8.5.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== -xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -706,8 +572,3 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zstd-codec@0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/zstd-codec/-/zstd-codec-0.1.5.tgz#c180193e4603ef74ddf704bcc835397d30a60e42" - integrity sha512-v3fyjpK8S/dpY/X5WxqTK3IoCnp/ZOLxn144GZVlNUjtwAchzrVo03h+oMATFhCIiJ5KTr4V3vDQQYz4RU684g== From 0a6bbb868c90dcd12ede9f17535670e5f2875c00 Mon Sep 17 00:00:00 2001 From: Michael Rittmeister Date: Wed, 6 Nov 2024 17:29:23 +0100 Subject: [PATCH 3/6] Make JVM implementation Java 8 compatible --- gateway/src/jvmMain/kotlin/ZstdDecompressor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gateway/src/jvmMain/kotlin/ZstdDecompressor.kt b/gateway/src/jvmMain/kotlin/ZstdDecompressor.kt index 49d45b281cd..698cda65574 100644 --- a/gateway/src/jvmMain/kotlin/ZstdDecompressor.kt +++ b/gateway/src/jvmMain/kotlin/ZstdDecompressor.kt @@ -12,7 +12,7 @@ internal actual fun ZstdDecompressor() = object : Decompressor { override fun Frame.decompress(): String { input.updateDelegate(data) - return zstdStream.readAllBytes().decodeToString() + return zstdStream.readBytes().decodeToString() } override fun close() { From 8a9d685e95c402493974d1869ccb7010cc74d108 Mon Sep 17 00:00:00 2001 From: Michael Rittmeister Date: Wed, 6 Nov 2024 17:29:33 +0100 Subject: [PATCH 4/6] Api dump --- core/api/core.api | 2 ++ core/api/core.klib.api | 3 +++ gateway/api/gateway.api | 47 +++++++++++++++++++++++++++++++++--- gateway/api/gateway.klib.api | 47 ++++++++++++++++++++++++++++++++++-- 4 files changed, 94 insertions(+), 5 deletions(-) diff --git a/core/api/core.api b/core/api/core.api index a038d4920bb..fb061317750 100644 --- a/core/api/core.api +++ b/core/api/core.api @@ -2184,6 +2184,7 @@ public abstract class dev/kord/core/builder/kord/BaseKordBuilder { public final fun cache (Lkotlin/jvm/functions/Function2;)V public final fun gateways (Lkotlin/jvm/functions/Function2;)V public final fun getApplicationId ()Ldev/kord/common/entity/Snowflake; + public final fun getCompression ()Ldev/kord/gateway/Compression; public final fun getDefaultDispatcher ()Lkotlinx/coroutines/CoroutineDispatcher; public final fun getDefaultStrategy ()Ldev/kord/core/supplier/EntitySupplyStrategy; public final fun getEventFlow ()Lkotlinx/coroutines/flow/MutableSharedFlow; @@ -2193,6 +2194,7 @@ public abstract class dev/kord/core/builder/kord/BaseKordBuilder { public final fun getToken ()Ljava/lang/String; public final fun requestHandler (Lkotlin/jvm/functions/Function1;)V public final fun setApplicationId (Ldev/kord/common/entity/Snowflake;)V + public final fun setCompression (Ldev/kord/gateway/Compression;)V public final fun setDefaultDispatcher (Lkotlinx/coroutines/CoroutineDispatcher;)V public final fun setDefaultStrategy (Ldev/kord/core/supplier/EntitySupplyStrategy;)V public final fun setEventFlow (Lkotlinx/coroutines/flow/MutableSharedFlow;)V diff --git a/core/api/core.klib.api b/core/api/core.klib.api index 23bc8491c80..7d5ace07109 100644 --- a/core/api/core.klib.api +++ b/core/api/core.klib.api @@ -1674,6 +1674,9 @@ abstract class dev.kord.core.builder.kord/BaseKordBuilder { // dev.kord.core.bui final var applicationId // dev.kord.core.builder.kord/BaseKordBuilder.applicationId|{}applicationId[0] final fun (): dev.kord.common.entity/Snowflake? // dev.kord.core.builder.kord/BaseKordBuilder.applicationId.|(){}[0] final fun (dev.kord.common.entity/Snowflake?) // dev.kord.core.builder.kord/BaseKordBuilder.applicationId.|(dev.kord.common.entity.Snowflake?){}[0] + final var compression // dev.kord.core.builder.kord/BaseKordBuilder.compression|{}compression[0] + final fun (): dev.kord.gateway/Compression // dev.kord.core.builder.kord/BaseKordBuilder.compression.|(){}[0] + final fun (dev.kord.gateway/Compression) // dev.kord.core.builder.kord/BaseKordBuilder.compression.|(dev.kord.gateway.Compression){}[0] final var defaultDispatcher // dev.kord.core.builder.kord/BaseKordBuilder.defaultDispatcher|{}defaultDispatcher[0] final fun (): kotlinx.coroutines/CoroutineDispatcher // dev.kord.core.builder.kord/BaseKordBuilder.defaultDispatcher.|(){}[0] final fun (kotlinx.coroutines/CoroutineDispatcher) // dev.kord.core.builder.kord/BaseKordBuilder.defaultDispatcher.|(kotlinx.coroutines.CoroutineDispatcher){}[0] diff --git a/gateway/api/gateway.api b/gateway/api/gateway.api index b73047ebda7..5b7c35693e0 100644 --- a/gateway/api/gateway.api +++ b/gateway/api/gateway.api @@ -219,6 +219,43 @@ public final class dev/kord/gateway/Command$SerializationStrategy : kotlinx/seri public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } +public abstract interface class dev/kord/gateway/Compression { + public abstract fun getName ()Ljava/lang/String; + public abstract fun newDecompressor ()Ldev/kord/gateway/Decompressor; +} + +public final class dev/kord/gateway/Compression$None : dev/kord/gateway/Compression { + public static final field INSTANCE Ldev/kord/gateway/Compression$None; + public fun equals (Ljava/lang/Object;)Z + public fun getName ()Ljava/lang/String; + public fun hashCode ()I + public fun newDecompressor ()Ldev/kord/gateway/Decompressor; + public fun toString ()Ljava/lang/String; +} + +public final class dev/kord/gateway/Compression$ZLib : dev/kord/gateway/Compression { + public static final field INSTANCE Ldev/kord/gateway/Compression$ZLib; + public fun equals (Ljava/lang/Object;)Z + public fun getName ()Ljava/lang/String; + public fun hashCode ()I + public fun newDecompressor ()Ldev/kord/gateway/Decompressor; + public fun toString ()Ljava/lang/String; +} + +public final class dev/kord/gateway/Compression$Zstd : dev/kord/gateway/Compression { + public static final field INSTANCE Ldev/kord/gateway/Compression$Zstd; + public fun equals (Ljava/lang/Object;)Z + public fun getName ()Ljava/lang/String; + public fun hashCode ()I + public fun newDecompressor ()Ldev/kord/gateway/Decompressor; + public fun toString ()Ljava/lang/String; +} + +public final class dev/kord/gateway/Decompressor$Noop : dev/kord/gateway/Decompressor { + public fun close ()V + public fun decompress (Lio/ktor/websocket/Frame;)Ljava/lang/String; +} + public final class dev/kord/gateway/DefaultGateway : dev/kord/gateway/Gateway { public static final field Companion Ldev/kord/gateway/DefaultGateway$Companion; public fun (Ldev/kord/gateway/DefaultGatewayData;)V @@ -238,6 +275,7 @@ public final class dev/kord/gateway/DefaultGatewayBuilder { public fun ()V public final fun build ()Ldev/kord/gateway/DefaultGateway; public final fun getClient ()Lio/ktor/client/HttpClient; + public final fun getCompression ()Ldev/kord/gateway/Compression; public final fun getDispatcher ()Lkotlinx/coroutines/CoroutineDispatcher; public final fun getEventFlow ()Lkotlinx/coroutines/flow/MutableSharedFlow; public final fun getIdentifyRateLimiter ()Ldev/kord/gateway/ratelimit/IdentifyRateLimiter; @@ -245,6 +283,7 @@ public final class dev/kord/gateway/DefaultGatewayBuilder { public final fun getSendRateLimiter ()Ldev/kord/common/ratelimit/RateLimiter; public final fun getUrl ()Ljava/lang/String; public final fun setClient (Lio/ktor/client/HttpClient;)V + public final fun setCompression (Ldev/kord/gateway/Compression;)V public final fun setDispatcher (Lkotlinx/coroutines/CoroutineDispatcher;)V public final fun setEventFlow (Lkotlinx/coroutines/flow/MutableSharedFlow;)V public final fun setIdentifyRateLimiter (Ldev/kord/gateway/ratelimit/IdentifyRateLimiter;)V @@ -254,7 +293,7 @@ public final class dev/kord/gateway/DefaultGatewayBuilder { } public final class dev/kord/gateway/DefaultGatewayData { - public fun (Ljava/lang/String;Lio/ktor/client/HttpClient;Ldev/kord/gateway/retry/Retry;Ldev/kord/common/ratelimit/RateLimiter;Ldev/kord/gateway/ratelimit/IdentifyRateLimiter;Lkotlinx/coroutines/CoroutineDispatcher;Lkotlinx/coroutines/flow/MutableSharedFlow;)V + public fun (Ljava/lang/String;Lio/ktor/client/HttpClient;Ldev/kord/gateway/retry/Retry;Ldev/kord/common/ratelimit/RateLimiter;Ldev/kord/gateway/ratelimit/IdentifyRateLimiter;Lkotlinx/coroutines/CoroutineDispatcher;Lkotlinx/coroutines/flow/MutableSharedFlow;Ldev/kord/gateway/Compression;)V public final fun component1 ()Ljava/lang/String; public final fun component2 ()Lio/ktor/client/HttpClient; public final fun component3 ()Ldev/kord/gateway/retry/Retry; @@ -262,10 +301,12 @@ public final class dev/kord/gateway/DefaultGatewayData { public final fun component5 ()Ldev/kord/gateway/ratelimit/IdentifyRateLimiter; public final fun component6 ()Lkotlinx/coroutines/CoroutineDispatcher; public final fun component7 ()Lkotlinx/coroutines/flow/MutableSharedFlow; - public final fun copy (Ljava/lang/String;Lio/ktor/client/HttpClient;Ldev/kord/gateway/retry/Retry;Ldev/kord/common/ratelimit/RateLimiter;Ldev/kord/gateway/ratelimit/IdentifyRateLimiter;Lkotlinx/coroutines/CoroutineDispatcher;Lkotlinx/coroutines/flow/MutableSharedFlow;)Ldev/kord/gateway/DefaultGatewayData; - public static synthetic fun copy$default (Ldev/kord/gateway/DefaultGatewayData;Ljava/lang/String;Lio/ktor/client/HttpClient;Ldev/kord/gateway/retry/Retry;Ldev/kord/common/ratelimit/RateLimiter;Ldev/kord/gateway/ratelimit/IdentifyRateLimiter;Lkotlinx/coroutines/CoroutineDispatcher;Lkotlinx/coroutines/flow/MutableSharedFlow;ILjava/lang/Object;)Ldev/kord/gateway/DefaultGatewayData; + public final fun component8 ()Ldev/kord/gateway/Compression; + public final fun copy (Ljava/lang/String;Lio/ktor/client/HttpClient;Ldev/kord/gateway/retry/Retry;Ldev/kord/common/ratelimit/RateLimiter;Ldev/kord/gateway/ratelimit/IdentifyRateLimiter;Lkotlinx/coroutines/CoroutineDispatcher;Lkotlinx/coroutines/flow/MutableSharedFlow;Ldev/kord/gateway/Compression;)Ldev/kord/gateway/DefaultGatewayData; + public static synthetic fun copy$default (Ldev/kord/gateway/DefaultGatewayData;Ljava/lang/String;Lio/ktor/client/HttpClient;Ldev/kord/gateway/retry/Retry;Ldev/kord/common/ratelimit/RateLimiter;Ldev/kord/gateway/ratelimit/IdentifyRateLimiter;Lkotlinx/coroutines/CoroutineDispatcher;Lkotlinx/coroutines/flow/MutableSharedFlow;Ldev/kord/gateway/Compression;ILjava/lang/Object;)Ldev/kord/gateway/DefaultGatewayData; public fun equals (Ljava/lang/Object;)Z public final fun getClient ()Lio/ktor/client/HttpClient; + public final fun getCompression ()Ldev/kord/gateway/Compression; public final fun getDispatcher ()Lkotlinx/coroutines/CoroutineDispatcher; public final fun getEventFlow ()Lkotlinx/coroutines/flow/MutableSharedFlow; public final fun getIdentifyRateLimiter ()Ldev/kord/gateway/ratelimit/IdentifyRateLimiter; diff --git a/gateway/api/gateway.klib.api b/gateway/api/gateway.klib.api index b2e60f175ae..47c5a236a47 100644 --- a/gateway/api/gateway.klib.api +++ b/gateway/api/gateway.klib.api @@ -94,6 +94,43 @@ abstract interface dev.kord.gateway/Gateway : kotlinx.coroutines/CoroutineScope } } +sealed interface dev.kord.gateway/Compression { // dev.kord.gateway/Compression|null[0] + abstract val name // dev.kord.gateway/Compression.name|{}name[0] + abstract fun (): kotlin/String? // dev.kord.gateway/Compression.name.|(){}[0] + + abstract fun newDecompressor(): dev.kord.gateway/Decompressor // dev.kord.gateway/Compression.newDecompressor|newDecompressor(){}[0] + + final object None : dev.kord.gateway/Compression { // dev.kord.gateway/Compression.None|null[0] + final val name // dev.kord.gateway/Compression.None.name|{}name[0] + final fun (): kotlin/String? // dev.kord.gateway/Compression.None.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // dev.kord.gateway/Compression.None.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // dev.kord.gateway/Compression.None.hashCode|hashCode(){}[0] + final fun newDecompressor(): dev.kord.gateway/Decompressor // dev.kord.gateway/Compression.None.newDecompressor|newDecompressor(){}[0] + final fun toString(): kotlin/String // dev.kord.gateway/Compression.None.toString|toString(){}[0] + } + + final object ZLib : dev.kord.gateway/Compression { // dev.kord.gateway/Compression.ZLib|null[0] + final val name // dev.kord.gateway/Compression.ZLib.name|{}name[0] + final fun (): kotlin/String // dev.kord.gateway/Compression.ZLib.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // dev.kord.gateway/Compression.ZLib.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // dev.kord.gateway/Compression.ZLib.hashCode|hashCode(){}[0] + final fun newDecompressor(): dev.kord.gateway/Decompressor // dev.kord.gateway/Compression.ZLib.newDecompressor|newDecompressor(){}[0] + final fun toString(): kotlin/String // dev.kord.gateway/Compression.ZLib.toString|toString(){}[0] + } + + final object Zstd : dev.kord.gateway/Compression { // dev.kord.gateway/Compression.Zstd|null[0] + final val name // dev.kord.gateway/Compression.Zstd.name|{}name[0] + final fun (): kotlin/String // dev.kord.gateway/Compression.Zstd.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // dev.kord.gateway/Compression.Zstd.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // dev.kord.gateway/Compression.Zstd.hashCode|hashCode(){}[0] + final fun newDecompressor(): dev.kord.gateway/Decompressor // dev.kord.gateway/Compression.Zstd.newDecompressor|newDecompressor(){}[0] + final fun toString(): kotlin/String // dev.kord.gateway/Compression.Zstd.toString|toString(){}[0] + } +} + final class dev.kord.gateway.builder/LoginBuilder { // dev.kord.gateway.builder/LoginBuilder|null[0] constructor () // dev.kord.gateway.builder/LoginBuilder.|(){}[0] @@ -405,6 +442,9 @@ final class dev.kord.gateway/DefaultGatewayBuilder { // dev.kord.gateway/Default final var client // dev.kord.gateway/DefaultGatewayBuilder.client|{}client[0] final fun (): io.ktor.client/HttpClient? // dev.kord.gateway/DefaultGatewayBuilder.client.|(){}[0] final fun (io.ktor.client/HttpClient?) // dev.kord.gateway/DefaultGatewayBuilder.client.|(io.ktor.client.HttpClient?){}[0] + final var compression // dev.kord.gateway/DefaultGatewayBuilder.compression|{}compression[0] + final fun (): dev.kord.gateway/Compression // dev.kord.gateway/DefaultGatewayBuilder.compression.|(){}[0] + final fun (dev.kord.gateway/Compression) // dev.kord.gateway/DefaultGatewayBuilder.compression.|(dev.kord.gateway.Compression){}[0] final var dispatcher // dev.kord.gateway/DefaultGatewayBuilder.dispatcher|{}dispatcher[0] final fun (): kotlinx.coroutines/CoroutineDispatcher // dev.kord.gateway/DefaultGatewayBuilder.dispatcher.|(){}[0] final fun (kotlinx.coroutines/CoroutineDispatcher) // dev.kord.gateway/DefaultGatewayBuilder.dispatcher.|(kotlinx.coroutines.CoroutineDispatcher){}[0] @@ -428,10 +468,12 @@ final class dev.kord.gateway/DefaultGatewayBuilder { // dev.kord.gateway/Default } final class dev.kord.gateway/DefaultGatewayData { // dev.kord.gateway/DefaultGatewayData|null[0] - constructor (kotlin/String, io.ktor.client/HttpClient, dev.kord.gateway.retry/Retry, dev.kord.common.ratelimit/RateLimiter, dev.kord.gateway.ratelimit/IdentifyRateLimiter, kotlinx.coroutines/CoroutineDispatcher, kotlinx.coroutines.flow/MutableSharedFlow) // dev.kord.gateway/DefaultGatewayData.|(kotlin.String;io.ktor.client.HttpClient;dev.kord.gateway.retry.Retry;dev.kord.common.ratelimit.RateLimiter;dev.kord.gateway.ratelimit.IdentifyRateLimiter;kotlinx.coroutines.CoroutineDispatcher;kotlinx.coroutines.flow.MutableSharedFlow){}[0] + constructor (kotlin/String, io.ktor.client/HttpClient, dev.kord.gateway.retry/Retry, dev.kord.common.ratelimit/RateLimiter, dev.kord.gateway.ratelimit/IdentifyRateLimiter, kotlinx.coroutines/CoroutineDispatcher, kotlinx.coroutines.flow/MutableSharedFlow, dev.kord.gateway/Compression) // dev.kord.gateway/DefaultGatewayData.|(kotlin.String;io.ktor.client.HttpClient;dev.kord.gateway.retry.Retry;dev.kord.common.ratelimit.RateLimiter;dev.kord.gateway.ratelimit.IdentifyRateLimiter;kotlinx.coroutines.CoroutineDispatcher;kotlinx.coroutines.flow.MutableSharedFlow;dev.kord.gateway.Compression){}[0] final val client // dev.kord.gateway/DefaultGatewayData.client|{}client[0] final fun (): io.ktor.client/HttpClient // dev.kord.gateway/DefaultGatewayData.client.|(){}[0] + final val compression // dev.kord.gateway/DefaultGatewayData.compression|{}compression[0] + final fun (): dev.kord.gateway/Compression // dev.kord.gateway/DefaultGatewayData.compression.|(){}[0] final val dispatcher // dev.kord.gateway/DefaultGatewayData.dispatcher|{}dispatcher[0] final fun (): kotlinx.coroutines/CoroutineDispatcher // dev.kord.gateway/DefaultGatewayData.dispatcher.|(){}[0] final val eventFlow // dev.kord.gateway/DefaultGatewayData.eventFlow|{}eventFlow[0] @@ -452,7 +494,8 @@ final class dev.kord.gateway/DefaultGatewayData { // dev.kord.gateway/DefaultGat final fun component5(): dev.kord.gateway.ratelimit/IdentifyRateLimiter // dev.kord.gateway/DefaultGatewayData.component5|component5(){}[0] final fun component6(): kotlinx.coroutines/CoroutineDispatcher // dev.kord.gateway/DefaultGatewayData.component6|component6(){}[0] final fun component7(): kotlinx.coroutines.flow/MutableSharedFlow // dev.kord.gateway/DefaultGatewayData.component7|component7(){}[0] - final fun copy(kotlin/String = ..., io.ktor.client/HttpClient = ..., dev.kord.gateway.retry/Retry = ..., dev.kord.common.ratelimit/RateLimiter = ..., dev.kord.gateway.ratelimit/IdentifyRateLimiter = ..., kotlinx.coroutines/CoroutineDispatcher = ..., kotlinx.coroutines.flow/MutableSharedFlow = ...): dev.kord.gateway/DefaultGatewayData // dev.kord.gateway/DefaultGatewayData.copy|copy(kotlin.String;io.ktor.client.HttpClient;dev.kord.gateway.retry.Retry;dev.kord.common.ratelimit.RateLimiter;dev.kord.gateway.ratelimit.IdentifyRateLimiter;kotlinx.coroutines.CoroutineDispatcher;kotlinx.coroutines.flow.MutableSharedFlow){}[0] + final fun component8(): dev.kord.gateway/Compression // dev.kord.gateway/DefaultGatewayData.component8|component8(){}[0] + final fun copy(kotlin/String = ..., io.ktor.client/HttpClient = ..., dev.kord.gateway.retry/Retry = ..., dev.kord.common.ratelimit/RateLimiter = ..., dev.kord.gateway.ratelimit/IdentifyRateLimiter = ..., kotlinx.coroutines/CoroutineDispatcher = ..., kotlinx.coroutines.flow/MutableSharedFlow = ..., dev.kord.gateway/Compression = ...): dev.kord.gateway/DefaultGatewayData // dev.kord.gateway/DefaultGatewayData.copy|copy(kotlin.String;io.ktor.client.HttpClient;dev.kord.gateway.retry.Retry;dev.kord.common.ratelimit.RateLimiter;dev.kord.gateway.ratelimit.IdentifyRateLimiter;kotlinx.coroutines.CoroutineDispatcher;kotlinx.coroutines.flow.MutableSharedFlow;dev.kord.gateway.Compression){}[0] final fun equals(kotlin/Any?): kotlin/Boolean // dev.kord.gateway/DefaultGatewayData.equals|equals(kotlin.Any?){}[0] final fun hashCode(): kotlin/Int // dev.kord.gateway/DefaultGatewayData.hashCode|hashCode(){}[0] final fun toString(): kotlin/String // dev.kord.gateway/DefaultGatewayData.toString|toString(){}[0] From cd550bec72491ffe82776e6ccb84f8d6ba5d70e6 Mon Sep 17 00:00:00 2001 From: Michael Rittmeister Date: Wed, 6 Nov 2024 17:36:05 +0100 Subject: [PATCH 5/6] [ci skip] Reformat ZstdDecompressor.kt --- gateway/src/jsMain/kotlin/ZstdDecompressor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gateway/src/jsMain/kotlin/ZstdDecompressor.kt b/gateway/src/jsMain/kotlin/ZstdDecompressor.kt index ad944552b71..da40ce044c6 100644 --- a/gateway/src/jsMain/kotlin/ZstdDecompressor.kt +++ b/gateway/src/jsMain/kotlin/ZstdDecompressor.kt @@ -1,6 +1,6 @@ package dev.kord.gateway - import dev.kord.gateway.internal.Decompress +import dev.kord.gateway.internal.Decompress import io.ktor.websocket.* import js.typedarrays.toUint8Array From 2b669519939a3fd8db7f8fc0363f87c386efdabb Mon Sep 17 00:00:00 2001 From: Michael Rittmeister Date: Thu, 7 Nov 2024 00:51:17 +0100 Subject: [PATCH 6/6] Use a better implementation for UpdatableByteArrayInputStream Co-authored-by: viztea <44017640+viztea@users.noreply.github.com> --- gateway/src/jvmMain/kotlin/ZstdDecompressor.kt | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/gateway/src/jvmMain/kotlin/ZstdDecompressor.kt b/gateway/src/jvmMain/kotlin/ZstdDecompressor.kt index 698cda65574..3c705bd0d39 100644 --- a/gateway/src/jvmMain/kotlin/ZstdDecompressor.kt +++ b/gateway/src/jvmMain/kotlin/ZstdDecompressor.kt @@ -3,7 +3,6 @@ package dev.kord.gateway import com.github.luben.zstd.ZstdInputStream import io.ktor.websocket.* import java.io.ByteArrayInputStream -import java.io.InputStream internal actual fun ZstdDecompressor() = object : Decompressor { @@ -11,7 +10,7 @@ internal actual fun ZstdDecompressor() = object : Decompressor { private val zstdStream = ZstdInputStream(input).apply { continuous = true } override fun Frame.decompress(): String { - input.updateDelegate(data) + input.update(data) return zstdStream.readBytes().decodeToString() } @@ -20,14 +19,10 @@ internal actual fun ZstdDecompressor() = object : Decompressor { } } -private class UpdatableByteArrayInputStream : InputStream() { - private var delegate: ByteArrayInputStream? = null - - private val d: InputStream get() = delegate ?: error("No data available") - - override fun read(): Int = d.read() - - fun updateDelegate(bytes: ByteArray) { - delegate = ByteArrayInputStream(bytes) +private class UpdatableByteArrayInputStream : ByteArrayInputStream(ByteArray(0)) { + fun update(newBuf: ByteArray) { + this.pos = 0 + this.buf = newBuf + this.count = newBuf.size } }