From e5e8ae759aa2140dcfcb51dc0dbf6cb1bee53fbd Mon Sep 17 00:00:00 2001 From: Victor Turansky Date: Tue, 29 Oct 2024 12:27:05 +0200 Subject: [PATCH] KTOR-6158 JS. Remove redundant `require` calls (#4422) * KTOR-6158 JS. Remove redundant `require` calls * KTOR-6158 JS. Remove redundant `readBodyNode` * KTOR-6158 JS. Remove invalid import * KTOR-6158 WasmJS. Remove redundant `require` calls * KTOR-6158 WasmJS. Fix `Object.assign` declaration * KTOR-6158 Update yarn.lock file --------- Co-authored-by: Osip Fatkullin --- gradle/libs.versions.toml | 2 - kotlin-js-store/yarn.lock | 19 ----- ktor-client/ktor-client-core/build.gradle.kts | 4 -- .../client/engine/js/compatibility/Utils.kt | 24 ++----- .../ktor/client/engine/js/node/NodeFetch.kt | 55 --------------- .../client/engine/js/compatibility/Utils.kt | 21 +++--- .../ktor/client/engine/js/node/NodeFetch.kt | 69 ------------------- .../src/io/ktor/client/utils/JsUtils.kt | 3 + 8 files changed, 17 insertions(+), 180 deletions(-) delete mode 100644 ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/node/NodeFetch.kt delete mode 100644 ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/node/NodeFetch.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e177a05557b..65a1a89131f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -57,8 +57,6 @@ thymeleaf = "3.1.2.RELEASE" javax-servlet = "4.0.1" jakarta-servlet = "5.0.0" -node-fetch = "2.6.7" -abort-controller = "3.0.0" ws = "8.5.0" xmlutil = "0.90.2" yamlkt = "0.13.0" diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index 0538dd63459..f843f35b35c 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -308,13 +308,6 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -abort-controller@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - accepts@~1.3.4: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" @@ -959,11 +952,6 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -1669,13 +1657,6 @@ netmask@^2.0.2: resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - node-fetch@^2.6.12: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" diff --git a/ktor-client/ktor-client-core/build.gradle.kts b/ktor-client/ktor-client-core/build.gradle.kts index 93921d23478..19fdad7c0a8 100644 --- a/ktor-client/ktor-client-core/build.gradle.kts +++ b/ktor-client/ktor-client-core/build.gradle.kts @@ -22,16 +22,12 @@ kotlin.sourceSets { jsMain { dependencies { - api(npm("node-fetch", libs.versions.node.fetch.get())) - api(npm("abort-controller", libs.versions.abort.controller.get())) api(npm("ws", libs.versions.ws.get())) } } wasmJsMain { dependencies { - api(npm("node-fetch", libs.versions.node.fetch.get())) - api(npm("abort-controller", libs.versions.abort.controller.get())) api(npm("ws", libs.versions.ws.get())) } } diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt index dbc05602c18..72cc8952d8f 100644 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt +++ b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt @@ -6,7 +6,6 @@ package io.ktor.client.engine.js.compatibility import io.ktor.client.engine.js.* import io.ktor.client.engine.js.browser.* -import io.ktor.client.engine.js.node.* import io.ktor.client.fetch.* import io.ktor.util.* import io.ktor.utils.io.* @@ -22,7 +21,7 @@ internal suspend fun commonFetch( PlatformUtils.IS_BROWSER -> fetch(input, init) else -> { val options = js("Object").assign(js("Object").create(null), init, config.nodeOptions) - jsRequireNodeFetch()(input, options) + fetch(input, options) } } @@ -37,25 +36,10 @@ internal suspend fun commonFetch( } internal fun AbortController(): AbortController { - return when { - PlatformUtils.IS_BROWSER -> js("new AbortController()") - else -> { - @Suppress("UNUSED_VARIABLE") - val controller = js("eval('require')('abort-controller')") - js("new controller()") - } - } + return js("new AbortController()") } internal fun CoroutineScope.readBody( response: org.w3c.fetch.Response -): ByteReadChannel = when { - PlatformUtils.IS_NODE -> readBodyNode(response) - else -> readBodyBrowser(response) -} - -private fun jsRequireNodeFetch(): dynamic = try { - js("eval('require')('node-fetch')") -} catch (cause: dynamic) { - throw Error("Error loading module 'node-fetch': $cause") -} +): ByteReadChannel = + readBodyBrowser(response) diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/node/NodeFetch.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/node/NodeFetch.kt deleted file mode 100644 index cd3dca017e3..00000000000 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/node/NodeFetch.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2014-2019 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -package io.ktor.client.engine.js.node - -import io.ktor.client.engine.js.* -import io.ktor.utils.io.* -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.* -import org.khronos.webgl.* -import org.w3c.fetch.* - -@OptIn(InternalCoroutinesApi::class) -internal fun CoroutineScope.readBodyNode(response: Response): ByteReadChannel = writer { - val body: dynamic = response.body ?: error("Fail to get body") - - val responseData = Channel(1) - - body.on("data") { chunk: ArrayBuffer -> - responseData.trySend(Uint8Array(chunk).asByteArray()).isSuccess - body.pause() - } - - body.on("error") { error -> - val cancelCause = runCatching { - coroutineContext.job.getCancellationException() - }.getOrNull() - if (cancelCause != null) { - responseData.cancel(cancelCause) - } else { - val cause = JsError(error) - responseData.close(cause) - } - } - - body.on("end") { - responseData.close() - } - - try { - for (chunk in responseData) { - channel.writeFully(chunk) - channel.flush() - body.resume() - } - } catch (cause: Throwable) { - val origin = runCatching { - coroutineContext.job.getCancellationException() - }.getOrNull() ?: cause - - body.destroy(origin) - throw origin - } -}.channel diff --git a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/compatibility/Utils.kt b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/compatibility/Utils.kt index 4425fc291eb..064a13c0a31 100644 --- a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/compatibility/Utils.kt +++ b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/compatibility/Utils.kt @@ -6,7 +6,6 @@ package io.ktor.client.engine.js.compatibility import io.ktor.client.engine.js.* import io.ktor.client.engine.js.browser.* -import io.ktor.client.engine.js.node.* import io.ktor.client.fetch.* import io.ktor.client.utils.* import io.ktor.util.* @@ -22,8 +21,13 @@ internal suspend fun commonFetch( val promise: Promise = when { PlatformUtils.IS_BROWSER -> fetch(input, init) else -> { - val nodeFetch = makeRequire("node-fetch") - makeJsCall>(nodeFetch, input.toJsString(), init, config.nodeOptions) + val options = makeJsCall( + jsObjectAssign(), + makeJsObject(), + init, + config.nodeOptions, + ) + fetch(input, options) } } @@ -43,16 +47,11 @@ private fun abortControllerCtorBrowser(): AbortController = js("AbortController") internal fun AbortController(): AbortController { - val ctor = when { - PlatformUtils.IS_BROWSER -> abortControllerCtorBrowser() - else -> makeRequire("abort-controller") - } + val ctor = abortControllerCtorBrowser() return makeJsNew(ctor) } internal fun CoroutineScope.readBody( response: org.w3c.fetch.Response -): ByteReadChannel = when { - PlatformUtils.IS_NODE -> readBodyNode(response) - else -> readBodyBrowser(response) -} +): ByteReadChannel = + readBodyBrowser(response) diff --git a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/node/NodeFetch.kt b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/node/NodeFetch.kt deleted file mode 100644 index c4aa4756635..00000000000 --- a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/engine/js/node/NodeFetch.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -package io.ktor.client.engine.js.node - -import io.ktor.client.engine.js.* -import io.ktor.client.utils.* -import io.ktor.utils.io.* -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.* -import org.khronos.webgl.* -import org.w3c.fetch.* - -internal external interface ResponseBody : JsAny { - fun pause(): Unit - fun resume(): Unit - fun destroy(cause: JsAny): Unit -} - -private fun bodyOn(body: ResponseBody, type: String, handler: (T) -> Unit): Unit = - js("body.on(type, handler)") - -private fun bodyOn(body: ResponseBody, type: String, handler: () -> Unit): Unit = - js("body.on(type, handler)") - -@OptIn(InternalCoroutinesApi::class) -internal fun CoroutineScope.readBodyNode(response: Response): ByteReadChannel = writer { - val body = response.body?.unsafeCast() ?: error("Fail to get body") - - val responseData = Channel(1) - - bodyOn(body, "data") { buffer: JsAny -> - responseData.trySend(Uint8Array(buffer.unsafeCast()).asByteArray()).isSuccess - body.pause() - } - - bodyOn(body, "error") { error: JsAny -> - val cancelCause = runCatching { - coroutineContext.job.getCancellationException() - }.getOrNull() - - if (cancelCause != null) { - responseData.cancel(cancelCause) - } else { - val cause = JsError(error) - responseData.close(cause) - } - } - - bodyOn(body, "end") { - responseData.close() - } - - try { - for (chunk in responseData) { - channel.writeFully(chunk) - channel.flush() - body.resume() - } - } catch (cause: Throwable) { - val origin = runCatching { - coroutineContext.job.getCancellationException() - }.getOrNull() ?: cause - - body.destroy(origin.toJsReference()) - throw origin - } -}.channel diff --git a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/utils/JsUtils.kt b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/utils/JsUtils.kt index 36816c3e965..7ff440a490a 100644 --- a/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/utils/JsUtils.kt +++ b/ktor-client/ktor-client-core/wasmJs/src/io/ktor/client/utils/JsUtils.kt @@ -8,6 +8,9 @@ import org.khronos.webgl.* internal fun makeJsObject(): T = js("{ return {}; }") +internal fun jsObjectAssign(): JsAny = + js("Object.assign") + @Suppress("UNUSED_PARAMETER") internal fun makeJsNew(ctor: JsAny): T = js("new ctor()")