Strange question, related to the above one. Curren...
# multiplatform
e
Strange question, related to the above one. Currently I return my own object from methods, which wraps a
Promise
or
CompletableFuture
, depending on the platform. Can I, at compile time, generate an additional method for each target (JS/JVM) to expose the private promise/future? Maybe with KSP? This would allow doing something like the following, in TS context:
Copy code
const result = await mySocket.connect(...).promise()
f
I think you can just put it the public value of the wrapper in the corresponding source direct for each platform. Or add a platform specific extension method published in the API.
e
@franztesca forgot to add that it's an
interface
Copy code
ZPromise      // interface - commonMain
- JsZPromise  // class - jsMain
- JvmZPromise // class - jvmMain
Even if I make the
promise
field public or add a method to expose it, it won't get built in the TS types declaration file
The extension function produces a top level function in TS
Copy code
export declare namespace my.namespace {
    function promise<T>(_this_: my.namespace.JsZPromise<T>): Promise<T>;
}
I've solved it with an
expect interface
, and in the actual interface for JS I've added a
Copy code
fun promise(): Promise<T>
method. What a mental trip
@turansky what's the scope for
expect interface
? I mean why is the above allowed? It's veeery strange
Copy code
expect interface ZPromise<T> {
  fun <S> then(thenFn: (T) -> S): ZPromise<S>
  fun <S> thenDeferred(thenFn: (T) -> ZPromise<S>): ZPromise<S>
  fun <S> catch(catchFn: (Throwable) -> S): ZPromise<S>
  fun <S> catchDeferred(catchFn: (Throwable) -> ZPromise<S>): ZPromise<S>
  fun finally(thenFn: (T?, Throwable?) -> Unit)
}
An in JS
Copy code
@JsExport
actual interface ZPromise<T> {
  fun promise(): Promise<T>
  actual fun <S> then(thenFn: (T) -> S): ZPromise<S>
  actual fun <S> thenDeferred(thenFn: (T) -> ZPromise<S>): ZPromise<S>
  actual fun <S> catch(catchFn: (Throwable) -> S): ZPromise<S>
  actual fun <S> catchDeferred(catchFn: (Throwable) -> ZPromise<S>): ZPromise<S>
  actual fun finally(thenFn: (T?, Throwable?) -> Unit)
}
t
I don’t understand your question 😞
e
@turansky oh I was just trying to understand what's the use case for
expect/actual interface
, it seems very weird to use it
a
for JS One way to resolve this interfacing issue is to have a helper function to convert to a
promise
instead of having it with the object it self (not ideal I know) so in
jsMain
extend your class
Copy code
fun <ResultT> YourClass<ResultT>.promise(): Promise<ResultT> {
        return Promise { success: (ResultT) -> Unit, failure: (Throwable) -> Unit ->
            onSuccess {
                success(it)
            }.onFailure {
                failure(it)
            }
        }
}
And your implementation would be like
const result = await YourClass.promise(mySocket.connect(...))
It's not ideal but still reusable and readable Example Usage
t
From my perspective actual typealias expected And if you need interface - you can use
PromiseLike
e
@turansky I've built my own object using the thenable concept, and it allows async/await anyway, it's just wrapped in a promise by the JS engine itself