Skip to content

Commit dc6e9f6

Browse files
authored
Restore Promise-related functions on Wasm/JS as HIDDEN (#4661)
1 parent 82eeb01 commit dc6e9f6

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

kotlinx-coroutines-core/api/kotlinx-coroutines-core.klib.api

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,8 +1294,20 @@ final fun <#A: kotlin.js/JsAny?> (kotlinx.coroutines/CoroutineScope).kotlinx.cor
12941294
// Targets: [wasmJs]
12951295
final fun <#A: kotlin.js/JsAny?> (kotlinx.coroutines/Deferred<#A>).kotlinx.coroutines/asPromise(): kotlin.js/Promise<#A> // kotlinx.coroutines/asPromise|asPromise@kotlinx.coroutines.Deferred<0:0>(){0§<kotlin.js.JsAny?>}[0]
12961296

1297+
// Targets: [wasmJs]
1298+
final fun <#A: kotlin/Any?> (kotlin.js/Promise<kotlin.js/JsAny?>).kotlinx.coroutines/asDeferred(): kotlinx.coroutines/Deferred<#A> // kotlinx.coroutines/asDeferred|asDeferred@kotlin.js.Promise<kotlin.js.JsAny?>(){0§<kotlin.Any?>}[0]
1299+
1300+
// Targets: [wasmJs]
1301+
final fun <#A: kotlin/Any?> (kotlinx.coroutines/CoroutineScope).kotlinx.coroutines/promise(kotlin.coroutines/CoroutineContext = ..., kotlinx.coroutines/CoroutineStart = ..., kotlin.coroutines/SuspendFunction1<kotlinx.coroutines/CoroutineScope, #A>): kotlin.js/Promise<kotlin.js/JsAny?> // kotlinx.coroutines/promise|promise@kotlinx.coroutines.CoroutineScope(kotlin.coroutines.CoroutineContext;kotlinx.coroutines.CoroutineStart;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,0:0>){0§<kotlin.Any?>}[0]
1302+
1303+
// Targets: [wasmJs]
1304+
final fun <#A: kotlin/Any?> (kotlinx.coroutines/Deferred<#A>).kotlinx.coroutines/asPromise(): kotlin.js/Promise<kotlin.js/JsAny?> // kotlinx.coroutines/asPromise|asPromise@kotlinx.coroutines.Deferred<0:0>(){0§<kotlin.Any?>}[0]
1305+
12971306
// Targets: [wasmJs]
12981307
final suspend fun <#A: kotlin.js/JsAny?> (kotlin.js/Promise<#A>).kotlinx.coroutines/await(): #A // kotlinx.coroutines/await|await@kotlin.js.Promise<0:0>(){0§<kotlin.js.JsAny?>}[0]
12991308

1309+
// Targets: [wasmJs]
1310+
final suspend fun <#A: kotlin/Any?> (kotlin.js/Promise<kotlin.js/JsAny?>).kotlinx.coroutines/await(): #A // kotlinx.coroutines/await|await@kotlin.js.Promise<kotlin.js.JsAny?>(){0§<kotlin.Any?>}[0]
1311+
13001312
// Targets: [wasmWasi]
13011313
final fun kotlinx.coroutines.internal/runTestCoroutine(kotlin.coroutines/CoroutineContext, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines/CoroutineScope, kotlin/Unit>) // kotlinx.coroutines.internal/runTestCoroutine|runTestCoroutine(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,kotlin.Unit>){}[0]

kotlinx-coroutines-core/wasmJs/src/Promise.wasm.kt

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
@file:OptIn(ExperimentalWasmJsInterop::class)
12
package kotlinx.coroutines
23

4+
import kotlin.coroutines.*
5+
import kotlin.js.*
6+
37
@OptIn(ExperimentalWasmJsInterop::class)
48
internal actual fun JsPromiseError.toThrowable(): Throwable = try {
59
unsafeCast<JsReference<Throwable>>().get()
@@ -9,3 +13,61 @@ internal actual fun JsPromiseError.toThrowable(): Throwable = try {
913

1014
@OptIn(ExperimentalWasmJsInterop::class)
1115
internal actual fun Throwable.toJsPromiseError(): JsPromiseError = toJsReference()
16+
17+
/*
18+
* All code after this line is preserved for compatibility with versions 1.10.2 and below.
19+
*/
20+
21+
@Suppress("UNUSED_PARAMETER")
22+
private fun promiseSetDeferred(promise: Promise<JsAny?>, deferred: JsAny): Unit =
23+
js("promise.deferred = deferred")
24+
25+
@Suppress("UNUSED_PARAMETER")
26+
private fun promiseGetDeferred(promise: Promise<JsAny?>): JsAny? = js("""{
27+
console.assert(promise instanceof Promise, "promiseGetDeferred must receive a promise, but got ", promise);
28+
return promise.deferred == null ? null : promise.deferred;
29+
}""")
30+
31+
@Deprecated("Moved to the 'web' source set", level = DeprecationLevel.HIDDEN)
32+
public fun <T> CoroutineScope.promise(
33+
context: CoroutineContext = EmptyCoroutineContext,
34+
start: CoroutineStart = CoroutineStart.DEFAULT,
35+
block: suspend CoroutineScope.() -> T
36+
): Promise<JsAny?> =
37+
async(context, start, block).oldAsPromiseImpl()
38+
39+
@Deprecated("Moved to the 'web' source set", level = DeprecationLevel.HIDDEN)
40+
public fun <T> Deferred<T>.asPromise(): Promise<JsAny?> = oldAsPromiseImpl()
41+
42+
private fun <T> Deferred<T>.oldAsPromiseImpl(): Promise<JsAny?> {
43+
val promise = Promise<JsAny?> { resolve, reject ->
44+
invokeOnCompletion {
45+
val e = getCompletionExceptionOrNull()
46+
if (e != null) {
47+
reject(e.toJsReference())
48+
} else {
49+
resolve(getCompleted()?.toJsReference())
50+
}
51+
}
52+
}
53+
promiseSetDeferred(promise, this.toJsReference())
54+
return promise
55+
}
56+
57+
@Deprecated("Moved to the 'web' source set", level = DeprecationLevel.HIDDEN)
58+
@Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE", "UNCHECKED_CAST")
59+
public fun <T> Promise<JsAny?>.asDeferred(): Deferred<T> {
60+
val deferred = promiseGetDeferred(this) as? JsReference<Deferred<T>>
61+
return deferred?.get() ?: GlobalScope.async(start = CoroutineStart.UNDISPATCHED) { oldAwaitImpl() }
62+
}
63+
64+
@Deprecated("Moved to the 'web' source set", level = DeprecationLevel.HIDDEN)
65+
public suspend fun <T> Promise<JsAny?>.await(): T = oldAwaitImpl()
66+
67+
@Suppress("UNCHECKED_CAST")
68+
private suspend fun <T> Promise<JsAny?>.oldAwaitImpl(): T = suspendCancellableCoroutine { cont: CancellableContinuation<T> ->
69+
this@oldAwaitImpl.then(
70+
onFulfilled = { cont.resume(it as T); null },
71+
onRejected = { cont.resumeWithException(it.toThrowableOrNull() ?: error("Unexpected non-Kotlin exception $it")); null }
72+
)
73+
}

0 commit comments

Comments
 (0)