Seskar is a gradle plugin that provides useful additions for Kotlin/JS projects.
To add Seskar to your project, you need to the following configuration to your project's build.gradle.kts
:
plugins {
kotlin("js") version "1.7.21"
id("io.github.turansky.seskar") version "0.20.0"
}
// browser target
dependencies {
implementation("io.github.turansky.seskar:seskar-core:0.20.0")
}
Seskar checks if interfaces that inherit from the Props
interface are external.
When a project uses the Kotlin/JS IR compiler, value classes
are autoboxed. If a value class
is used as a dependency
of a react hook (e.g., in useMemo
, useState
or useEffect
), a new class will be created on every rendering pass,
which causes infinite re-rendering.
To prevent this, Seskar provides a @JsValue
marker, which disables autoboxing for value class
dependencies in hooks.
Also, it converts Long
values to String
.
Seskar supports Duration
by default, so no @JsValue
marker is needed.
import seskar.js.JsValue
@JsValue
value class Count(
private val value: Int,
)
val Counter = VFC {
val count: Count = useCount()
useEffect(count) {
println("Count changed: $count")
}
}
function Counter() {
var count = useCount()
useEffect(
() => {
println(`Count changed: $count`)
},
// AUTOBOXING
[ new Count(count) ],
)
}
function Counter() {
var count = useCount()
useEffect(
() => {
println(`Count changed: $count`)
},
// NO AUTOBOXING
[ count ],
)
}
Use enum constant as union value
// TypeScript
type Align = 'TOP' | 'LEFT' | 'BOTTOM' | 'RIGHT'
// Kotlin
import seskar.js.JsUnion
@JsUnion
external enum class Align {
TOP,
LEFT,
BOTTOM,
RIGHT,
;
}
println(Align.TOP) // 'TOP'
println(Align.LEFT) // 'LEFT'
// TypeScript
type LayoutOrientation = 'top-to-bottom'
| 'left-to-right'
| 'bottom-to-top'
| 'right-to-left'
// Kotlin
import seskar.js.JsUnion
import seskar.js.Case
@JsUnion(case = Case.KEBAB)
external enum class LayoutOrientation {
TOP_TO_BOTTOM, // 'top-to-bottom'
LEFT_TO_RIGHT, // 'left-to-right'
bottomToTop, // 'bottom-to-top'
rightToLeft, // 'right-to-left'
;
}
// TypeScript
type LayoutOrientation = 'top_to_bottom'
| 'left_to_right'
| 'bottom_to_top'
| 'right_to_left'
// Kotlin
import seskar.js.JsUnion
import seskar.js.Case
@JsUnion(case = Case.SNAKE)
external enum class LayoutOrientation {
TOP_TO_BOTTOM, // 'top_to_bottom'
LEFT_TO_RIGHT, // 'left_to_right'
bottomToTop, // 'bottom_to_top'
rightToLeft, // 'right_to_left'
;
}
Use String
or Int
constant as union value
// TypeScript
type Align = 't' | 'l' | 'b' | 'r'
// Kotlin
import seskar.js.JsUnion
import seskar.js.JsValue
@JsUnion
external enum class CustomAlign {
@JsString("t")
TOP,
@JsString("l")
LEFT,
@JsString("b")
BOTTOM,
@JsString("r")
RIGHT,
;
}
println(CustomAlign.TOP) // 't'
println(CustomAlign.LEFT) // 'l'
// TypeScript
type GRAPH_ITEM_TYPE_NODE = 1
type GRAPH_ITEM_TYPE_EDGE = 2
type GRAPH_ITEM_TYPE_PORT = 3
type GRAPH_ITEM_TYPE_LABEL = 4
type GraphItemType = GRAPH_ITEM_TYPE_NODE
| GRAPH_ITEM_TYPE_EDGE
| GRAPH_ITEM_TYPE_PORT
| GRAPH_ITEM_TYPE_LABEL
// Kotlin
import seskar.js.JsInt
import seskar.js.JsValue
@JsUnion
external enum class GraphItemType {
@JsInt(1)
NODE,
@JsInt(2)
EDGE,
@JsInt(4)
PORT,
@JsInt(8)
LABEL,
;
}
println(GraphItemType.EDGE) // 2
println(GraphItemType.PORT) // 4
TBD