CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-kotlin--kotlin-stdlib-wasm-js

Kotlin Standard Library for experimental WebAssembly JS platform providing core functionality and JavaScript interoperability

Pending
Overview
Eval results
Files

promises.mddocs/

Promise Support

JavaScript Promise integration with full async/await support and error handling for asynchronous operations in Kotlin/Wasm.

Capabilities

Promise Class

JavaScript Promise object with comprehensive support for asynchronous operations.

/**
 * JavaScript Promise object for asynchronous operations
 * @param T Type of the resolved value (must extend JsAny?)
 * @param executor Function that receives resolve and reject callbacks
 */
external class Promise<out T : JsAny?>(
    executor: (resolve: (T) -> Unit, reject: (JsAny) -> Unit) -> Unit
) : JsAny

Promise Methods

Chain operations and handle promise results with standard JavaScript Promise methods.

/**
 * Register fulfillment handler for the promise
 * @param onFulfilled Callback for successful resolution
 * @return Promise<S> New promise with transformed result
 */
fun <S : JsAny?> Promise<T>.then(onFulfilled: ((T) -> S)?): Promise<S>

/**
 * Register fulfillment and rejection handlers for the promise
 * @param onFulfilled Callback for successful resolution
 * @param onRejected Callback for rejection
 * @return Promise<S> New promise with transformed result
 */
fun <S : JsAny?> Promise<T>.then(
    onFulfilled: ((T) -> S)?, 
    onRejected: ((JsAny) -> S)?
): Promise<S>

/**
 * Register rejection handler for the promise
 * @param onRejected Callback for handling rejection
 * @return Promise<S> New promise with handled result
 */
fun <S : JsAny?> Promise<T>.catch(onRejected: (JsAny) -> S): Promise<S>

/**
 * Register cleanup handler that runs regardless of promise outcome
 * @param onFinally Callback for cleanup operations
 * @return Promise<T> Promise with same result but with cleanup
 */
fun Promise<T>.finally(onFinally: () -> Unit): Promise<T>

Promise Companion Object

Static methods for creating and combining promises.

/**
 * Wait for all promises to resolve
 * @param promise Array of promises to wait for
 * @return Promise<JsArray<out S>> Promise resolving to array of results
 */
fun <S : JsAny?> Promise.Companion.all(
    promise: JsArray<out Promise<S>>
): Promise<JsArray<out S>>

/**
 * Wait for first promise to resolve or reject
 * @param promise Array of promises to race
 * @return Promise<S> Promise resolving to first completed result
 */
fun <S : JsAny?> Promise.Companion.race(
    promise: JsArray<out Promise<S>>
): Promise<S>

/**
 * Create rejected promise with given reason
 * @param e Rejection reason
 * @return Promise<Nothing> Rejected promise
 */
fun Promise.Companion.reject(e: JsAny): Promise<Nothing>

/**
 * Create resolved promise with given value
 * @param e Value to resolve with
 * @return Promise<S> Resolved promise
 */
fun <S : JsAny?> Promise.Companion.resolve(e: S): Promise<S>

/**
 * Create resolved promise from another promise
 * @param e Promise to resolve with
 * @return Promise<S> Promise with same resolution
 */
fun <S : JsAny?> Promise.Companion.resolve(e: Promise<S>): Promise<S>

/**
 * Create resolved promise with no value (void)
 * @return Promise<Unit> Resolved promise with unit value
 */
fun Promise.Companion.resolve(): Promise<Unit>

Usage Examples:

Basic Promise Creation

import kotlin.js.*

// Create a simple promise
val promise = Promise<JsString> { resolve, reject ->
    val success = true // Some condition
    if (success) {
        resolve("Operation successful!".toJsString())
    } else {
        reject("Operation failed".toJsString())
    }
}

// Handle the promise
promise
    .then { result ->
        println("Success: $result")
        result
    }
    .catch { error ->
        println("Error: $error")
        "default".toJsString()
    }
    .finally {
        println("Cleanup operations")
    }

Async Data Fetching

// Simulating an API call
fun fetchUserData(userId: String): Promise<JsString> {
    return Promise { resolve, reject ->
        // Simulate async operation
        js("""
            setTimeout(() => {
                if (arguments[0] === "valid") {
                    arguments[1]('{"name": "Alice", "age": 25}');
                } else {
                    arguments[2]('User not found');
                }
            }, 1000);
        """)(userId, resolve, reject)
    }
}

// Use the promise
fetchUserData("valid")
    .then { userData ->
        println("User data: $userData")
        userData
    }
    .catch { error ->
        println("Failed to fetch user: $error")
        "{}".toJsString()
    }

Promise Chaining

// Chain multiple asynchronous operations
fun processDataPipeline(input: String): Promise<JsString> {
    return Promise.resolve(input.toJsString())
        .then { data ->
            // Step 1: Validate data
            println("Validating: $data")
            if (data.toString().isNotEmpty()) {
                data
            } else {
                throw Exception("Invalid data")
            }
        }
        .then { validData ->
            // Step 2: Transform data
            println("Transforming: $validData")
            validData.toString().uppercase().toJsString()
        }
        .then { transformedData ->
            // Step 3: Save data
            println("Saving: $transformedData")
            "Saved: $transformedData".toJsString()
        }
}

// Use the pipeline
processDataPipeline("hello world")
    .then { result ->
        println("Pipeline result: $result")
        result
    }
    .catch { error ->
        println("Pipeline error: $error")
        "Error occurred".toJsString()
    }

Promise.all for Parallel Operations

// Execute multiple promises in parallel
fun fetchMultipleResources(): Promise<JsArray<out JsString>> {
    val promises = arrayOf(
        Promise.resolve("Resource 1".toJsString()),
        Promise.resolve("Resource 2".toJsString()),
        Promise.resolve("Resource 3".toJsString())
    ).toJsArray()
    
    return Promise.all(promises)
}

// Wait for all to complete
fetchMultipleResources()
    .then { results ->
        println("All resources loaded:")
        for (i in 0 until results.length) {
            println("- ${results[i]}")
        }
        results
    }
    .catch { error ->
        println("One or more resources failed: $error")
        arrayOf<JsString>().toJsArray()
    }

Promise.race for Timeout Implementation

// Implement timeout using Promise.race
fun withTimeout<T : JsAny?>(
    promise: Promise<T>, 
    timeoutMs: Int
): Promise<T> {
    val timeoutPromise = Promise<T> { _, reject ->
        js("""
            setTimeout(() => {
                arguments[0]('Operation timed out');
            }, arguments[1]);
        """)(reject, timeoutMs)
    }
    
    val promises = arrayOf(promise, timeoutPromise).toJsArray()
    return Promise.race(promises)
}

// Use with timeout
val slowOperation = Promise<JsString> { resolve, _ ->
    js("""
        setTimeout(() => {
            arguments[0]('Slow operation completed');
        }, 3000);
    """)(resolve)
}

withTimeout(slowOperation, 2000)
    .then { result ->
        println("Operation completed: $result")
        result
    }
    .catch { error ->
        println("Operation failed or timed out: $error")
        "timeout".toJsString()
    }

Integration with JavaScript APIs

// Wrapper for fetch API
@JsFun("(url, options) => fetch(url, options)")
external fun jsFetch(url: String, options: JsAny?): Promise<JsAny>

fun httpGet(url: String): Promise<JsString> {
    return jsFetch(url, null)
        .then { response ->
            // Check if response is ok
            val ok = js("arguments[0].ok")(response) as Boolean
            if (ok) {
                js("arguments[0].text()")(response) as Promise<JsString>
            } else {
                Promise.reject("HTTP Error".toJsString())
            }
        }
        .then { text ->
            text
        }
}

// Use the HTTP wrapper
httpGet("https://api.example.com/data")
    .then { responseText ->
        println("Response: $responseText")
        responseText
    }
    .catch { error ->
        println("HTTP request failed: $error")
        "".toJsString()
    }

Error Handling Patterns

// Comprehensive error handling
fun robustAsyncOperation(): Promise<JsString> {
    return Promise<JsString> { resolve, reject ->
        try {
            // Simulate operation that might throw
            val result = performSomeOperation()
            resolve(result.toJsString())
        } catch (e: Exception) {
            reject(e.message?.toJsString() ?: "Unknown error".toJsString())
        }
    }
    .catch { jsError ->
        // Convert JavaScript errors to meaningful messages
        val errorMessage = when {
            jsError is JsString -> jsError.toString()
            else -> "Unexpected error: $jsError"
        }
        
        println("Handled error: $errorMessage")
        "Error handled gracefully".toJsString()
    }
}

private fun performSomeOperation(): String {
    // Simulate some operation
    return "Operation result"
}

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-stdlib-wasm-js

docs

index.md

js-annotations.md

js-types.md

platform-services.md

promises.md

type-conversion.md

tile.json