Skip to content

Convert xiuper-ui to Kotlin Multiplatform to support wasmJs and other platforms #515

@phodal

Description

@phodal

Background

Currently, xiuper-ui is a JVM-only module (using kotlin("jvm") plugin), which means:

  • NanoDSL parser and IR generation are only available on JVM platforms
  • StatefulNanoRenderer cannot be used on wasmJs, JS, iOS, Android platforms
  • The wasmJs version of NanoDSLBlockRenderer has to use a simplified implementation without live preview

Goal

Convert xiuper-ui to a Kotlin Multiplatform module to enable:

  • ✅ Full NanoDSL parsing on all platforms (JVM, wasmJs, JS, Android, iOS)
  • ✅ Live UI preview with StatefulNanoRenderer on wasmJs and other platforms
  • ✅ Unified codebase across all platforms

Analysis

Core Code (Platform-agnostic, can move to commonMain)

  • NanoDSL.kt - Main DSL facade
  • NanoIR.kt, NanoIRConverter.kt - IR representation and conversion
  • IndentParser.kt, NanoParser.kt - Parser implementation
  • NanoSpec.kt, NanoSpecV1.kt - DSL specification
  • NanoNode.kt, Binding.kt - AST nodes
  • NanoAction.kt, NanoActionHandler.kt - Action handling
  • NanoState.kt, NanoStateManager.kt - State management
  • NanoRenderer.kt, HtmlRenderer.kt, NanoRenderContext.kt - Rendering
  • PromptTemplate.kt - Prompt templates
  • Evaluator.kt - Evaluation framework

JVM-Specific Code (needs expect/actual)

  1. ConfigLoader.kt - Uses File, System.getProperty("user.home")
  2. DslEvalRunner.kt - Uses File, System.getenv(), KotlinLogging
  3. DslToHtmlRenderer.kt - Uses File
  4. DslValidator.kt - Uses File
  5. TestSuite.kt, TestCase.kt - Uses System.currentTimeMillis()
  6. SuiteFileFormat.kt - Uses File

Implementation Plan

  • Step 1: Convert build.gradle.kts from kotlin("jvm") to kotlin("multiplatform")

    • Configure source sets: commonMain, jvmMain, wasmJsMain, androidMain, iosMain
    • Move dependencies to appropriate source sets
  • Step 2: Restructure source code

    • Create src/commonMain/kotlin directory
    • Move core code (NanoDSL, parser, IR, etc.) to commonMain
    • Keep existing code in src/main/kotlin → rename to src/jvmMain/kotlin
  • Step 3: Create expect/actual for platform-specific APIs

    • Create expect declarations in commonMain for:
      • File I/O operations
      • System properties (user.home, environment variables)
      • Current timestamp
      • Logging
    • Implement actual in jvmMain (existing JVM implementation)
    • Implement actual in wasmJsMain (stub or browser-compatible implementation)
  • Step 4: Update mpp-ui to use multiplatform xiuper-ui

    • Update NanoDSLBlockRenderer.wasmJs.kt to use full parser and renderer
    • Remove simplified wasmJs implementation
    • Test on all platforms
  • Step 5: Build and test

    • Run ./gradlew :xiuper-ui:build to ensure all platforms compile
    • Run ./gradlew :mpp-ui:wasmJsBrowserProductionWebpack to test wasmJs
    • Verify NanoDSL live preview works on wasmJs

Benefits

  1. Unified codebase: Same NanoDSL parser and renderer across all platforms
  2. Better user experience: Live preview on web (wasmJs) and mobile platforms
  3. Easier maintenance: No need to maintain separate implementations
  4. Future-proof: Easy to add new platforms (iOS, Android, etc.)

Related Files

  • xiuper-ui/build.gradle.kts
  • mpp-ui/src/wasmJsMain/kotlin/cc/unitmesh/devins/ui/compose/sketch/NanoDSLBlockRenderer.wasmJs.kt
  • mpp-ui/src/jvmMain/kotlin/cc/unitmesh/devins/ui/compose/sketch/NanoDSLBlockRenderer.jvm.kt

References

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions