feat: add Kotlin/Wasm (wasmJs) target - #426
Conversation
- Enable wasmJs target in build.gradle.kts (browser + nodejs + library)
- Add npm('mqtt') dependency for wasmJs source set
- Create webMain intermediate source set (shared by js + wasmJs):
- MkttClient.web.kt: actual factory function
- MqttClientWrapper.kt: expect class abstracting platform JS interop
- MqttJsClient.kt: refactored to delegate to MqttClientWrapper
- Add jsMain/MqttClientWrapper.js.kt: actual using dynamic types + object literals
- Add wasmJsMain/facade/MqttJsFacade.kt: wasmJs facade using JsAny, Promise
- Add wasmJsMain/MqttClientWrapper.wasmJs.kt: wasmJs actual using js() intrinsics
- Delete superseded jsMain files (MkttClient.js.kt, MqttJsClient.kt, adapter/MkttJsAdapter.kt)
Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com>
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 28028363 | Triggered | Generic Password | 29b0819 | src/wasmJsMain/kotlin/io/github/nicolasfara/facade/MqttJsFacade.kt | View secret |
| 15856367 | Triggered | Generic Password | e48dcba | src/jsMain/kotlin/io/github/nicolasfara/adapter/MkttJsAdapter.kt | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secrets safely. Learn here the best practices.
- Revoke and rotate these secrets.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
- Rename lambda variable 'w' to 'willConfig' in MqttClientWrapper.js.kt - Add @Suppress annotations for false-positive detekt warnings in wasmJs (UnusedParameter: parameters referenced inside js() string literals; MatchingDeclarationName: standard KMP platform-suffix naming convention; MaxLineLength: js() requires a single non-splittable string literal) Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com>
| } | ||
|
|
||
| actual suspend fun publish(topic: String, message: String, qos: Int) { | ||
| @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") |
There was a problem hiding this comment.
Yes — changed the publishAsync(…, options: IClientPublishOptions) overload in the wasmJs facade to accept JsAny instead. Since the underlying JS API treats it as a plain object anyway, the js() result can now be passed directly without any cast or suppression. Fixed in d448338.
JS: add typed PacketInfo external interface to JS facade, use it in on() callback so packet.qos and packet.retain are already typed — no cast needed. wasmJs: change publishAsync(…, options) in wasmJs facade to accept JsAny instead of IClientPublishOptions, so the js() result can be passed directly without any cast. Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com>
|
@copilot update the README.md with new compatibility info |
Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com>
| jsMain.dependencies { | ||
| implementation(npm("mqtt", "5.13.3")) | ||
| } | ||
| wasmJsMain.dependencies { | ||
| implementation(npm("mqtt", "5.13.3")) | ||
| } |
There was a problem hiding this comment.
Can the two dependencies (that are the same) can be refactored into a super source set? @copilot
There was a problem hiding this comment.
Done in 014b9a5. The duplicate npm("mqtt", "5.13.3") declarations have been replaced with a single one in webMain, declared via creating with an explicit dependsOn(commonMain). Both jsMain and wasmJsMain then call dependsOn(webMain), so both targets still get the npm dependency transitively.
Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot, the last CI fails, but no timeout and executes forever |
Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com>
The |
Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com>
Adds
wasmJsas a supported target while keeping the existingjsimplementation untouched to avoid regressions.JS module
Restored to the original
2.0.2state — no changes from the pre-PR baseline.wasmJs module (new, standalone)
Mirrors the
jsMainstructure without sharing code via an intermediate source set:src/wasmJsMain/…/facade/MqttJsFacade.kt—@JsModule("mqtt")external declarations usingJsAny/Promise(nodynamic)src/wasmJsMain/…/MqttJsClient.kt— fullMkttClientimplementation; Buffer→ByteArray conversion and JS object construction via top-leveljs()helper functions (required by Kotlin/Wasm's single-expression restriction)src/wasmJsMain/…/MkttClient.wasmJs.kt—actual fun createMqttClient(…)factoryBuild
wasmJs { browser { … }; nodejs { … }; binaries.library() }added tobuild.gradle.ktswithuseMocha { timeout = "1m" }on both sub-targets (prevents CI hangs on broker connection)npm("mqtt", "5.13.3")declared independently injsMainandwasmJsMain(no sharedwebMainintermediate source set)Platform support
js()wasmJs()wasmWasi()✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.