Skip to content

Commit 6e6cfb2

Browse files
whyolegosipxd
authored andcommitted
KTOR-7675 Support CIO client for wasm-js and js (#4441)
* Support multiple client engines for JS/WasmJs * CIO client Js/WasmJs support * Enable CIO tests in client tests * Make client engines `data object` to have `toString` * Make ClientLoader work with multiple engines on js/wasmJs and so test CIO engine on nodejs(js+wasmJs)
1 parent da4320f commit 6e6cfb2

File tree

68 files changed

+397
-404
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+397
-404
lines changed

ktor-client/ktor-client-android/api/ktor-client-android.api

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
public final class io/ktor/client/engine/android/Android : io/ktor/client/engine/HttpClientEngineFactory {
22
public static final field INSTANCE Lio/ktor/client/engine/android/Android;
33
public fun create (Lkotlin/jvm/functions/Function1;)Lio/ktor/client/engine/HttpClientEngine;
4+
public fun equals (Ljava/lang/Object;)Z
5+
public fun hashCode ()I
6+
public fun toString ()Ljava/lang/String;
47
}
58

69
public final class io/ktor/client/engine/android/AndroidClientEngine : io/ktor/client/engine/HttpClientEngineBase {

ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/Android.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import io.ktor.client.engine.*
2626
*
2727
* You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html).
2828
*/
29-
public object Android : HttpClientEngineFactory<AndroidEngineConfig> {
29+
public data object Android : HttpClientEngineFactory<AndroidEngineConfig> {
3030
override fun create(block: AndroidEngineConfig.() -> Unit): HttpClientEngine =
3131
AndroidClientEngine(AndroidEngineConfig().apply(block))
3232
}

ktor-client/ktor-client-apache/api/ktor-client-apache.api

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
public final class io/ktor/client/engine/apache/Apache : io/ktor/client/engine/HttpClientEngineFactory {
22
public static final field INSTANCE Lio/ktor/client/engine/apache/Apache;
33
public fun create (Lkotlin/jvm/functions/Function1;)Lio/ktor/client/engine/HttpClientEngine;
4+
public fun equals (Ljava/lang/Object;)Z
5+
public fun hashCode ()I
6+
public fun toString ()Ljava/lang/String;
47
}
58

69
public final class io/ktor/client/engine/apache/ApacheEngineConfig : io/ktor/client/engine/HttpClientEngineConfig {

ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/Apache.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import io.ktor.client.engine.*
2525
*
2626
* You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html).
2727
*/
28-
public object Apache : HttpClientEngineFactory<ApacheEngineConfig> {
28+
public data object Apache : HttpClientEngineFactory<ApacheEngineConfig> {
2929
override fun create(block: ApacheEngineConfig.() -> Unit): HttpClientEngine {
3030
val config = ApacheEngineConfig().apply(block)
3131
return ApacheEngine(config)

ktor-client/ktor-client-apache5/api/ktor-client-apache5.api

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
public final class io/ktor/client/engine/apache5/Apache5 : io/ktor/client/engine/HttpClientEngineFactory {
22
public static final field INSTANCE Lio/ktor/client/engine/apache5/Apache5;
33
public fun create (Lkotlin/jvm/functions/Function1;)Lio/ktor/client/engine/HttpClientEngine;
4+
public fun equals (Ljava/lang/Object;)Z
5+
public fun hashCode ()I
6+
public fun toString ()Ljava/lang/String;
47
}
58

69
public final class io/ktor/client/engine/apache5/Apache5EngineConfig : io/ktor/client/engine/HttpClientEngineConfig {

ktor-client/ktor-client-apache5/jvm/src/io/ktor/client/engine/apache5/Apache5.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import io.ktor.client.engine.*
2525
*
2626
* You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html).
2727
*/
28-
public object Apache5 : HttpClientEngineFactory<Apache5EngineConfig> {
28+
public data object Apache5 : HttpClientEngineFactory<Apache5EngineConfig> {
2929
override fun create(block: Apache5EngineConfig.() -> Unit): HttpClientEngine {
3030
val config = Apache5EngineConfig().apply(block)
3131
return Apache5Engine(config)

ktor-client/ktor-client-cio/api/ktor-client-cio.klib.api

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Klib ABI Dump
2-
// Targets: [androidNativeArm32, androidNativeArm64, androidNativeX64, androidNativeX86, iosArm64, iosSimulatorArm64, iosX64, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64]
2+
// Targets: [androidNativeArm32, androidNativeArm64, androidNativeX64, androidNativeX86, iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64]
33
// Rendering settings:
44
// - Signature version: 2
55
// - Show manifest properties: true
@@ -62,3 +62,7 @@ final object io.ktor.client.engine.cio/CIO : io.ktor.client.engine/HttpClientEng
6262
}
6363

6464
final fun (io.ktor.client.engine.cio/CIOEngineConfig).io.ktor.client.engine.cio/endpoint(kotlin/Function1<io.ktor.client.engine.cio/EndpointConfig, kotlin/Unit>): io.ktor.client.engine.cio/EndpointConfig // io.ktor.client.engine.cio/endpoint|[email protected](kotlin.Function1<io.ktor.client.engine.cio.EndpointConfig,kotlin.Unit>){}[0]
65+
66+
// Targets: [js]
67+
final val io.ktor.client.engine.cio/initHook // io.ktor.client.engine.cio/initHook|{}initHook[0]
68+
final fun <get-initHook>(): dynamic // io.ktor.client.engine.cio/initHook.<get-initHook>|<get-initHook>(){}[0]

ktor-client/ktor-client-cio/jvmAndPosix/src/io/ktor/client/engine/cio/CIOCommon.kt renamed to ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOCommon.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ import io.ktor.client.engine.*
2626
* You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html).
2727
*/
2828
public data object CIO : HttpClientEngineFactory<CIOEngineConfig> {
29-
init {
30-
addToLoader()
31-
}
32-
3329
override fun create(block: CIOEngineConfig.() -> Unit): HttpClientEngine =
3430
CIOEngine(CIOEngineConfig().apply(block))
3531
}

ktor-client/ktor-client-cio/jvmAndPosix/src/io/ktor/client/engine/cio/CIOEngine.kt renamed to ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOEngine.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ internal class CIOEngine(
6161
val requestJob = requestField[Job]!!
6262
val selector = selectorManager
6363

64-
@OptIn(ExperimentalCoroutinesApi::class)
6564
GlobalScope.launch(parentContext, start = CoroutineStart.ATOMIC) {
6665
try {
6766
requestJob.join()

ktor-client/ktor-client-cio/jvmAndPosix/test/CIOEngineTest.kt renamed to ktor-client/ktor-client-cio/common/test/CIOEngineTest.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import io.ktor.client.tests.utils.*
1212
import io.ktor.http.*
1313
import io.ktor.network.selector.*
1414
import io.ktor.network.sockets.*
15+
import io.ktor.test.dispatcher.*
1516
import io.ktor.utils.io.*
1617
import io.ktor.websocket.*
1718
import kotlinx.coroutines.*
@@ -24,7 +25,7 @@ class CIOEngineTest {
2425
private val selectorManager = SelectorManager()
2526

2627
@Test
27-
fun testRequestTimeoutIgnoredWithWebSocket(): Unit = runBlocking {
28+
fun testRequestTimeoutIgnoredWithWebSocket() = runTestWithRealTime {
2829
val client = HttpClient(CIO) {
2930
engine {
3031
requestTimeout = 10
@@ -48,7 +49,7 @@ class CIOEngineTest {
4849
}
4950

5051
@Test
51-
fun testRequestTimeoutIgnoredWithSSE(): Unit = runBlocking {
52+
fun testRequestTimeoutIgnoredWithSSE() = runTestWithRealTime {
5253
val client = HttpClient(CIO) {
5354
engine {
5455
requestTimeout = 10
@@ -67,7 +68,7 @@ class CIOEngineTest {
6768
}
6869

6970
@Test
70-
fun testExpectHeader(): Unit = runBlocking {
71+
fun testExpectHeader() = runTestWithRealTime {
7172
val body = "Hello World"
7273

7374
withServerSocket { socket ->
@@ -95,7 +96,7 @@ class CIOEngineTest {
9596
}
9697

9798
@Test
98-
fun testNoExpectHeaderIfNoBody(): Unit = runBlocking {
99+
fun testNoExpectHeaderIfNoBody() = runTestWithRealTime {
99100
withServerSocket { socket ->
100101
val client = HttpClient(CIO)
101102
launch {
@@ -116,7 +117,7 @@ class CIOEngineTest {
116117
}
117118

118119
@Test
119-
fun testDontWaitForContinueResponse(): Unit = runBlocking {
120+
fun testDontWaitForContinueResponse() = runTestWithRealTime {
120121
withTimeout(30.seconds) {
121122
val body = "Hello World\n"
122123

@@ -148,7 +149,7 @@ class CIOEngineTest {
148149
}
149150

150151
@Test
151-
fun testRepeatRequestAfterExpectationFailed(): Unit = runBlocking {
152+
fun testRepeatRequestAfterExpectationFailed() = runTestWithRealTime {
152153
val body = "Hello World"
153154

154155
withServerSocket { socket ->

ktor-client/ktor-client-cio/jvmAndPosix/test/ConnectionFactoryTest.kt renamed to ktor-client/ktor-client-cio/common/test/ConnectionFactoryTest.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package io.ktor.client.engine.cio
66

77
import io.ktor.network.selector.*
88
import io.ktor.network.sockets.*
9+
import io.ktor.test.dispatcher.*
10+
import io.ktor.utils.io.core.*
911
import kotlinx.coroutines.*
1012
import kotlin.test.*
1113

@@ -24,7 +26,7 @@ class ConnectionFactoryTest {
2426
}
2527

2628
@Test
27-
fun testLimitSemaphore() = runBlocking {
29+
fun testLimitSemaphore() = runTestWithRealTime {
2830
val connectionFactory = ConnectionFactory(
2931
selectorManager,
3032
connectionsLimit = 2,
@@ -45,7 +47,7 @@ class ConnectionFactoryTest {
4547
}
4648

4749
@Test
48-
fun testAddressSemaphore() = runBlocking {
50+
fun testAddressSemaphore() = runTestWithRealTime {
4951
val connectionFactory = ConnectionFactory(
5052
selectorManager,
5153
connectionsLimit = 2,
@@ -68,7 +70,7 @@ class ConnectionFactoryTest {
6870
}
6971

7072
@Test
71-
fun testReleaseLimitSemaphoreWhenFailed() = runBlocking {
73+
fun testReleaseLimitSemaphoreWhenFailed() = runTestWithRealTime {
7274
val connectionFactory = ConnectionFactory(
7375
selectorManager,
7476
connectionsLimit = 2,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#
2+
# Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
#
4+
target.js.browser=false
5+
target.wasmJs.browser=false
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package io.ktor.client.engine.cio
6+
7+
import io.ktor.client.engine.*
8+
import io.ktor.util.*
9+
import io.ktor.utils.io.*
10+
11+
@Suppress("DEPRECATION")
12+
@OptIn(ExperimentalStdlibApi::class, ExperimentalJsExport::class, InternalAPI::class)
13+
@Deprecated("", level = DeprecationLevel.HIDDEN)
14+
@JsExport
15+
@EagerInitialization
16+
public val initHook: dynamic = run {
17+
if (PlatformUtils.IS_NODE) engines.append(CIO)
18+
}

ktor-client/ktor-client-cio/jvm/src/io/ktor/client/engine/cio/LoaderJvm.kt

Lines changed: 0 additions & 8 deletions
This file was deleted.

ktor-client/ktor-client-cio/jvmAndPosix/src/io/ktor/client/engine/cio/Loader.kt

Lines changed: 0 additions & 7 deletions
This file was deleted.

ktor-client/ktor-client-cio/posix/src/io/ktor/client/engine/cio/ConnectionPipelineNative.kt renamed to ktor-client/ktor-client-cio/nonJvm/src/io/ktor/client/engine/cio/ConnectionPipeline.nonJvm.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ internal actual class ConnectionPipeline actual constructor(
2121
actual override val coroutineContext: CoroutineContext = parentContext
2222

2323
init {
24-
error("Pipelining is not supported in native CIO")
24+
error("Pipelining is not supported in native/js/wasm CIO")
2525
}
2626

2727
actual val pipelineContext: Job
28-
get() = error("Pipelining is not supported in native CIO")
28+
get() = error("Pipelining is not supported in native/js/wasm CIO")
2929
}

ktor-client/ktor-client-cio/posix/src/io/ktor/client/engine/cio/LoaderNative.kt renamed to ktor-client/ktor-client-cio/posix/src/io/ktor/client/engine/cio/Loader.posix.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ package io.ktor.client.engine.cio
77
import io.ktor.client.engine.*
88
import io.ktor.utils.io.*
99

10-
@OptIn(ExperimentalStdlibApi::class)
10+
@Suppress("DEPRECATION")
11+
@OptIn(ExperimentalStdlibApi::class, InternalAPI::class)
1112
@EagerInitialization
12-
private val initHook = CIO
13-
14-
@OptIn(InternalAPI::class)
15-
internal actual fun addToLoader() {
16-
engines.append(CIO)
17-
}
13+
private val initHook = engines.append(CIO)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package io.ktor.client.engine.cio
6+
7+
import io.ktor.client.engine.*
8+
import io.ktor.util.*
9+
import io.ktor.utils.io.*
10+
11+
@Suppress("DEPRECATION")
12+
@OptIn(InternalAPI::class, ExperimentalStdlibApi::class)
13+
@EagerInitialization
14+
private val initHook: Unit = run {
15+
if (PlatformUtils.IS_NODE) engines.append(CIO)
16+
}

ktor-client/ktor-client-core/api/ktor-client-core.klib.api

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,11 @@ final object io.ktor.client.engine/ProxyBuilder { // io.ktor.client.engine/Proxy
11611161
final fun socks(kotlin/String, kotlin/Int): io.ktor.client.engine/ProxyConfig // io.ktor.client.engine/ProxyBuilder.socks|socks(kotlin.String;kotlin.Int){}[0]
11621162
}
11631163

1164+
final object io.ktor.client.engine/engines : kotlin.collections/Iterable<io.ktor.client.engine/HttpClientEngineFactory<io.ktor.client.engine/HttpClientEngineConfig>> { // io.ktor.client.engine/engines|null[0]
1165+
final fun append(io.ktor.client.engine/HttpClientEngineFactory<io.ktor.client.engine/HttpClientEngineConfig>) // io.ktor.client.engine/engines.append|append(io.ktor.client.engine.HttpClientEngineFactory<io.ktor.client.engine.HttpClientEngineConfig>){}[0]
1166+
final fun iterator(): kotlin.collections/Iterator<io.ktor.client.engine/HttpClientEngineFactory<io.ktor.client.engine/HttpClientEngineConfig>> // io.ktor.client.engine/engines.iterator|iterator(){}[0]
1167+
}
1168+
11641169
final object io.ktor.client.plugins.api/Send : io.ktor.client.plugins.api/ClientHook<kotlin.coroutines/SuspendFunction2<io.ktor.client.plugins.api/Send.Sender, io.ktor.client.request/HttpRequestBuilder, io.ktor.client.call/HttpClientCall>> { // io.ktor.client.plugins.api/Send|null[0]
11651170
final fun install(io.ktor.client/HttpClient, kotlin.coroutines/SuspendFunction2<io.ktor.client.plugins.api/Send.Sender, io.ktor.client.request/HttpRequestBuilder, io.ktor.client.call/HttpClientCall>) // io.ktor.client.plugins.api/Send.install|install(io.ktor.client.HttpClient;kotlin.coroutines.SuspendFunction2<io.ktor.client.plugins.api.Send.Sender,io.ktor.client.request.HttpRequestBuilder,io.ktor.client.call.HttpClientCall>){}[0]
11661171

@@ -1512,12 +1517,6 @@ final suspend inline fun <#A: reified kotlin/Any?> (io.ktor.client.plugins.webso
15121517
final suspend inline fun <#A: reified kotlin/Any?> (io.ktor.client.plugins.websocket/DefaultClientWebSocketSession).io.ktor.client.plugins.websocket/sendSerialized(#A) // io.ktor.client.plugins.websocket/sendSerialized|sendSerialized@io.ktor.client.plugins.websocket.DefaultClientWebSocketSession(0:0){0§<kotlin.Any?>}[0]
15131518
final suspend inline fun <#A: reified kotlin/Any?> (io.ktor.client.statement/HttpResponse).io.ktor.client.call/body(): #A // io.ktor.client.call/body|[email protected](){0§<kotlin.Any?>}[0]
15141519

1515-
// Targets: [native]
1516-
final object io.ktor.client.engine/engines : kotlin.collections/Iterable<io.ktor.client.engine/HttpClientEngineFactory<io.ktor.client.engine/HttpClientEngineConfig>> { // io.ktor.client.engine/engines|null[0]
1517-
final fun append(io.ktor.client.engine/HttpClientEngineFactory<io.ktor.client.engine/HttpClientEngineConfig>) // io.ktor.client.engine/engines.append|append(io.ktor.client.engine.HttpClientEngineFactory<io.ktor.client.engine.HttpClientEngineConfig>){}[0]
1518-
final fun iterator(): kotlin.collections/Iterator<io.ktor.client.engine/HttpClientEngineFactory<io.ktor.client.engine/HttpClientEngineConfig>> // io.ktor.client.engine/engines.iterator|iterator(){}[0]
1519-
}
1520-
15211520
// Targets: [js, wasmJs]
15221521
abstract interface io.ktor.client.fetch/AbortSignal : io.ktor.client.fetch/EventTarget { // io.ktor.client.fetch/AbortSignal|null[0]
15231522
abstract var aborted // io.ktor.client.fetch/AbortSignal.aborted|{}aborted[0]
@@ -1786,6 +1785,9 @@ open class io.ktor.client.engine.js/JsClientEngineConfig : io.ktor.client.engine
17861785
// Targets: [js, wasmJs]
17871786
final object io.ktor.client.engine.js/Js : io.ktor.client.engine/HttpClientEngineFactory<io.ktor.client.engine.js/JsClientEngineConfig> { // io.ktor.client.engine.js/Js|null[0]
17881787
final fun create(kotlin/Function1<io.ktor.client.engine.js/JsClientEngineConfig, kotlin/Unit>): io.ktor.client.engine/HttpClientEngine // io.ktor.client.engine.js/Js.create|create(kotlin.Function1<io.ktor.client.engine.js.JsClientEngineConfig,kotlin.Unit>){}[0]
1788+
final fun equals(kotlin/Any?): kotlin/Boolean // io.ktor.client.engine.js/Js.equals|equals(kotlin.Any?){}[0]
1789+
final fun hashCode(): kotlin/Int // io.ktor.client.engine.js/Js.hashCode|hashCode(){}[0]
1790+
final fun toString(): kotlin/String // io.ktor.client.engine.js/Js.toString|toString(){}[0]
17891791
}
17901792

17911793
// Targets: [js, wasmJs]
@@ -2179,6 +2181,10 @@ abstract interface io.ktor.client.fetch/Uint8ArrayConstructor { // io.ktor.clien
21792181
abstract fun of(kotlin/Array<out kotlin/Number>...): io.ktor.client.fetch/Uint8Array // io.ktor.client.fetch/Uint8ArrayConstructor.of|of(kotlin.Array<out|kotlin.Number>...){}[0]
21802182
}
21812183

2184+
// Targets: [js]
2185+
final val io.ktor.client.engine.js/initHook // io.ktor.client.engine.js/initHook|{}initHook[0]
2186+
final fun <get-initHook>(): dynamic // io.ktor.client.engine.js/initHook.<get-initHook>|<get-initHook>(){}[0]
2187+
21822188
// Targets: [js]
21832189
final inline fun (io.ktor.client.fetch/Uint8Array).io.ktor.client.fetch/get(kotlin/Number): kotlin/Number? // io.ktor.client.fetch/get|[email protected](kotlin.Number){}[0]
21842190

ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/Js.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
/*
2-
* Copyright 2014-2019 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
2+
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

55
package io.ktor.client.engine.js
66

77
import io.ktor.client.engine.*
8+
import io.ktor.utils.io.*
89

910
/**
1011
* A JavaScript client engine that uses the fetch API to execute requests.
@@ -20,7 +21,7 @@ import io.ktor.client.engine.*
2021
*
2122
* You can learn more about client engines from [Engines](https://ktor.io/docs/http-client-engines.html).
2223
*/
23-
public actual object Js : HttpClientEngineFactory<JsClientEngineConfig> {
24+
public actual data object Js : HttpClientEngineFactory<JsClientEngineConfig> {
2425
override fun create(block: JsClientEngineConfig.() -> Unit): HttpClientEngine =
2526
JsClientEngine(JsClientEngineConfig().apply(block))
2627
}
@@ -45,3 +46,10 @@ public actual open class JsClientEngineConfig : HttpClientEngineConfig() {
4546
*/
4647
public var nodeOptions: dynamic = js("Object").create(null)
4748
}
49+
50+
@Suppress("DEPRECATION")
51+
@OptIn(ExperimentalStdlibApi::class, ExperimentalJsExport::class, InternalAPI::class)
52+
@Deprecated("", level = DeprecationLevel.HIDDEN)
53+
@JsExport
54+
@EagerInitialization
55+
public val initHook: dynamic = engines.append(Js)

ktor-client/ktor-client-core/jsAndWasmShared/src/io/ktor/client/HttpClientJs.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
/*
2-
* Copyright 2014-2019 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
2+
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

55
package io.ktor.client
66

7+
import io.ktor.client.engine.*
78
import io.ktor.client.engine.js.*
89
import io.ktor.utils.io.*
910

@@ -16,4 +17,9 @@ import io.ktor.utils.io.*
1617
@KtorDsl
1718
public actual fun HttpClient(
1819
block: HttpClientConfig<*>.() -> Unit
19-
): HttpClient = HttpClient(JsClient(), block)
20+
): HttpClient = HttpClient(FACTORY, block)
21+
22+
// we need to fall back to the default (Js) engine if there are no other engines,
23+
// but in the presence of other engines, they're preferred.
24+
@OptIn(InternalAPI::class)
25+
private val FACTORY = engines.firstOrNull { it != Js } ?: Js

0 commit comments

Comments
 (0)