FraunhoferISST / TREND

Traceability Enforcement of Datatransfers (TREND)
https://fraunhoferisst.github.io/TREND/
Other
5 stars 2 forks source link

Make watermarker library usable as JavaScript library #24

Open hnorkowski opened 1 month ago

hnorkowski commented 1 month ago

🚀 Feature Request

Current Problem

The watermarker library is usable in Java and Kotlin. It is possible to use the library in the browser by using a Kotlin frontend like KVision. However, it is currently not possible to import the library into plain JavaScript.

Proposed Solution

Evaluate what is required to export the library as JavaScript library

Additional Context

More information: https://kotlinlang.org/docs/js-to-kotlin-interop.html

gemdav commented 2 weeks ago

One possible (but maybe not the most elegant) solution is to use the @JsExport annotation that can be imported using import kotlin.js.JsExport. Find more information here. As this annotation is currently still experimental, it has to be opted in and used like follows:

import kotlin.js.JsExport
...
@OptIn(kotlin.js.ExperimentalJsExport::class)
@JsExport
class TextWatermark private constructor(
    content: List<Byte>,
    private val compression: Boolean,
) : Watermark(content) {
    /** Returns the uncompressed bytes from the Watermark */
    fun getBytes(): Result<List<Byte>> {
        return if (compression) {
            Compression.inflate(content)
        } else {
            Result.success(content)
        }
    }
[](url)
    /** Parses the uncompressed bytes as String */
    fun getText(): Result<String> {
    ...

There are a few things to be mentioned here:

  1. As JS does not support function overloading, the @JsName("[FunctionName]") annotation has to be used for overloaded functions like those in the Result class.
    
    /** Creates a new Result<T> from [status] and [value] */
    @JsName("intoResult")
    fun <T> into(value: T? = null) = Result(this.status, value)

/* Converts Result to Status / @JsName("intoStatus") fun into(): Status = this.status

More information can be found [here](https://kotlinlang.org/docs/js-to-kotlin-interop.html#jsname-annotation).

2. For the generation of JS code to work, the `build.gradle.kts` file has to be adapted like follows:

kotlin { ... js(IR) { browser { } binaries.executable() } ... }


More information can be found [here](https://kotlinlang.org/docs/js-project-setup.html#execution-environments).

3. When everything is configurated correctly, the JS code can be generated using `.\gradlew build`. By default, the source code will be placed in the `./build/js/packages/watermarker/kotlin/` directory. A minified version will be placed in the `./build/dist/js/productionExecutable/` directory.

4. I have not yet been able to investigate, whether the `@JsExport` annotation has to be used for every class, or if dependencies can be resolved automatically.

5. There might be more elegant options to generate JS code from kotlin that I am currently unaware of.