Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ private fun KotlinCommonCompilerOptions.configureGlobalKotlinArgumentsAndOptIns(
optIn.addAll(
"kotlin.experimental.ExperimentalTypeInference",
"kotlin.js.ExperimentalJsExport",
"kotlin.js.ExperimentalJsStatic",
// our own opt-ins that we don't want to bother with in our own code:
"kotlinx.coroutines.DelicateCoroutinesApi",
"kotlinx.coroutines.ExperimentalCoroutinesApi",
Expand Down
3 changes: 3 additions & 0 deletions kotlinx-coroutines-core/common/src/channels/BufferOverflow.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package kotlinx.coroutines.channels

import kotlinx.coroutines.internal.JsOptionalExport

/**
* A strategy for buffer overflow handling in [channels][Channel] and [flows][kotlinx.coroutines.flow.Flow] that
* controls what is going to be sacrificed on buffer overflow:
Expand All @@ -11,6 +13,7 @@ package kotlinx.coroutines.channels
* - [DROP_LATEST] — the buffer remains unchanged on overflow, and the value that we were going to add
* gets discarded, all without suspending.
*/
@JsOptionalExport(couldBeConvertedToExplicitExport = true)
public enum class BufferOverflow {
/**
* Suspend until free space appears in the buffer.
Expand Down
30 changes: 30 additions & 0 deletions kotlinx-coroutines-core/common/src/channels/Channel.common.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,8 @@ public interface ChannelIterator<out E> {
* > Note that if any work happens between `openResource()` and `channel.send(...)`,
* > it is your responsibility to ensure that resource gets closed in case this additional code fails.
*/

@JsOptionalExport(couldBeConvertedToExplicitExport = true)
public interface Channel<E> : SendChannel<E>, ReceiveChannel<E> {
/**
* Constants for the channel factory function `Channel()`.
Expand Down Expand Up @@ -1413,6 +1415,34 @@ public interface Channel<E> : SendChannel<E>, ReceiveChannel<E> {
internal val CHANNEL_DEFAULT_CAPACITY = systemProp(DEFAULT_BUFFER_PROPERTY_NAME,
64, 1, UNLIMITED - 1
)

/**
* Creates a new [Channel] for JavaScript/TypeScript interop.
*
* This factory is intended for JS export scenarios that rely on `@JsOptionalExport`.
* It allows creating channels from JavaScript only when [Channel] is reachable through
* an exported declaration signature, instead of unconditionally exporting the top-level
* `Channel(...)` factory.
*
* This helps avoid keeping extra JS-exported API surface when it is not used.
*
* Behavior is equivalent to:
* `Channel(capacity, onBufferOverflow, onUndeliveredElement)`.
*
* @param capacity Channel buffer capacity. Defaults to [RENDEZVOUS].
* @param onBufferOverflow Buffer overflow strategy. Defaults to [BufferOverflow.SUSPEND].
* @param onUndeliveredElement Optional callback invoked for each element that was sent
* but could not be delivered to a receiver.
*
* @return A newly created [Channel] instance.
*/
@JsStatic
@Suppress("NOTHING_TO_INLINE")
public inline fun <E> of(
capacity: Int = RENDEZVOUS,
onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND,
noinline onUndeliveredElement: ((E) -> Unit)? = null
): Channel<E> = Channel(capacity, onBufferOverflow, onUndeliveredElement)
}
}

Expand Down