Skip to content

Conversation

@dirkwa
Copy link
Contributor

@dirkwa dirkwa commented Dec 5, 2025

  • Add AssemblyScript plugin SDK for WASM plugin development
  • Support WASM plugins written in Rust, Go, .NET, and AssemblyScript
  • Implement Component Model bindings for SignalK API
  • Add plugin lifecycle management (load, start, stop, unload)
  • Support multiple WASM formats (Component Model, standard WASM)
  • Add TCP socket API for network-capable WASM plugins
  • Implement plugin configuration storage via plugin-config-data
  • Support WASM plugin HTTP endpoints and webapps
  • Add comprehensive documentation and example plugins
  • Fix Asyncify race conditions for network-capable WASM plugins
  • Make WASM runtime toggleable via server settings

WASM Implementation

Documentation

wasm/
├── README.md                    # Quick reference, current status
├── IMPLEMENTATION_HISTORY.md    # Detailed development history
├── WASM_PLUGIN_DEV_GUIDE.md    # Developer documentation
├── CHANGELOG.md                 # Version changelog
├── ASYNCIFY_IMPLEMENTATION.md   # Technical details on Asyncify
└── JS_TS_WASM_SUPPORT.md       # JS/TS WASM support notes

Example WASM Plugins

JS/TS

RUST

  • anchor-watch-rust
    • showcase for put handler, compiled on x86, runs on arm64
    • showcase for registering custom http endpoints (REST)
  • signalk-mayara-radar - FORK REWRITE as PROOF OF CONCEPT
    • fork of Marine Yacht Radar server to WASM
    • showcase for detecting Furuno DRS4D-NXT
    • not for use.

GO

  • charts-provider-go
    • showchase Charts Provider, that also emits deltas
    • showcase hybrid (WASM GO for filestore and webapp, Node.js for better-sqlite3)

C# .NET

@tkurki tkurki changed the title new: Add WASM functionality to Signal K including examples Add support for WASM plugins (with examples) Dec 5, 2025
@tkurki
Copy link
Member

tkurki commented Dec 5, 2025

As I commented earlier I don't think doing away with the need for restarts is worth the trouble, but instead what you have here is really really interesting and pushing us forward. Just the ability to run a wasm radar server demonstrates the possibilities.

Since this is such an elephant I'll probably make several review passes, so don't expect the first one include everything.

Copy link
Member

@tkurki tkurki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please npm run format and npm run lint and fix lint errors.

Prefer import over require (lint will tell you that). Prefer typing things over adding ignore comments for any complaints.

I don't think we need to add the special support for wasm debugging, especially the serverroute. If this is something that you think would be useful let's think about the general case of configuring debugging for troubleshooting different kinds of problems. for the end user something being WASM should not be of special concern. Like, why should they care?

@tkurki tkurki added the feature label Dec 5, 2025
@dirkwa
Copy link
Contributor Author

dirkwa commented Dec 6, 2025

I don't think we need to add the special support for wasm debugging, especially the serverroute. If this is something that you think would be useful let's think about the general case of configuring debugging for troubleshooting different kinds of problems. for the end user something being WASM should not be of special concern. Like, why should they care?

For WASM developers it is very helpful. It is nicely integrated and can be disbled by default:

image

@tkurki
Copy link
Member

tkurki commented Dec 8, 2025

I appreciate the comment that you'll continue the work, but no need to comment on each item until each has been addressed.

@tkurki
Copy link
Member

tkurki commented Dec 8, 2025

Git technique: you are merging master to this branch, which causes extra commits that are just noise. Please read up on rebasing - in general rebasing on master is a much better option: no extra merge commits and if conflicts arise you face them early and the branch will be eventually ready for merging to master.

@dirkwa
Copy link
Contributor Author

dirkwa commented Dec 9, 2025

Thank you very much that you take your time and push this so much.
I am very happy about this. I have addressed all the topics from above.
Meanwhile I made great progress with the MaYaRa wasm plugin using WebGPU.
Also I added hotplug - that reduches the server restarts massively.

PR: WASM Plugin Support with Hotplug

Summary

Adds WebAssembly plugin support to Signal K Server with complete hotplug lifecycle management. WASM plugins run alongside traditional Node.js plugins with the same enable/disable, install/uninstall behavior.

Changes

Core WASM Runtime

  • WASM runtime (src/wasm/) - Complete runtime for loading and executing AssemblyScript plugins
  • Server API bindings - Plugin access to Signal K delta updates, subscriptions, storage
  • Plugin ID derivation - Automatic ID from npm package name (e.g., @meri-imern/signalk-anchor-watchmeri-imern-signalk-anchor-watch)
  • Manifest handling - wasmManifest field in package.json for WASM-specific metadata

Plugin Hotplug

  • Unified hotplug for both Node.js and WASM plugins
  • Webapp filtering - 4-layer architecture ensures disabled plugin webapps never appear in Admin UI
  • Route blocking - Direct URL access to disabled plugin webapps returns 404
  • WebSocket cache - Filtered webapps list updated at startup

SDK

  • AssemblyScript SDK moved into monorepo (packages/signalk-plugin-sdk-wasm/)
  • Standard plugin interface: start(), stop(), registerWithRouter()

Documentation

  • WASM plugin development guide integrated into main docs
  • Internal maintainer documentation (docs/internal/hotplug.md)
  • Radar API documentation (experimental)

Tests

  • Plugin hotplug filtering tests (test/plugin-hotplug.ts)
  • Mock-based testing without external plugin dependencies
  • Removed obsolete skipped tests

Examples

  • Example plugins renamed with example- prefix to clarify non-production status
  • Folder names match npm package names

Files Changed

140 files changed, 25,572 insertions, 80 deletions

Key New Files

Path Description
src/wasm/wasm-runtime.ts WASM plugin loading and lifecycle
src/wasm/wasm-serverapi.ts Server API bindings for WASM
src/wasm/wasm-storage.ts Plugin storage implementation
src/wasm/wasm-subscriptions.ts Delta subscriptions for WASM
packages/signalk-plugin-sdk-wasm/ AssemblyScript SDK
test/plugin-hotplug.ts Hotplug filtering tests
docs/internal/hotplug.md Maintainer documentation
docs/develop/rest-api/radar_api.md Radar API (experimental)

Breaking Changes

None. WASM support is enabled by default.

Testing

npm test  # 124 tests passing

@tkurki
Copy link
Member

tkurki commented Dec 9, 2025

See 2eda5f0 - let’s not include the radar API in this PR. I am thrilled about the possibilities there, but want to get Kees et al involved in the discussion, that is kinda orthogonal to adding wasm support. I assume the mayara plugin will also see separate development, so splitting it to another PR with the radar API would be the best way forward imho.

@dirkwa
Copy link
Contributor Author

dirkwa commented Dec 9, 2025

As I understood you don't want me to comment every point, so I just "resolved" the ones that I have adressed and fixed. And comment on the important topics.

@dirkwa
Copy link
Contributor Author

dirkwa commented Dec 9, 2025

See 2eda5f0 - let’s not include the radar API in this PR. I am thrilled about the possibilities there, but want to get Kees et al involved in the discussion, that is kinda orthogonal to adding wasm support. I assume the mayara plugin will also see separate development, so splitting it to another PR with the radar API would be the best way forward imho.

I also struggled with this and wondered whether I should include it or not. In principle, we were almost in agreement, but the one open issue that he didn't respond to was whether we need a control websocket because the radar models are too different. However, we won't know the answer to that for another six months or a year, once everything has been tested and we have gained more experience.

In the coming days, I will primarily work on MayaRa and focus my attention on control, not image enhancement. Then we should see whether the API has matured enough by the time of the merge or whether we should remove it before the “final merge.”

As I see we are merging to a 3.x alpha - so even remonving from the last beta before RC would be still ok imho.

I hope you agree with this approach.

@dirkwa
Copy link
Contributor Author

dirkwa commented Dec 12, 2025

@tkurki

I successfully tested all functions of my furuno radar with the Radar API (v5) in the last build.
Due to it's design I am very sure that on the server side we do not need to touch it anymore.

Would love to see it merge. Let me know if you want me to change any additional things within this PR.

Copy link
Member

@tkurki tkurki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to stop this round now, continue over the weekend.

Tried to make suggestions as much as I could to make it easy to incporporate the feedback.

This is looking mighty good!

Copy link
Member

@tkurki tkurki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next pass, more comments. Still ways to go...

Copy link
Member

@tkurki tkurki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More review comments.

Copy link
Member

@tkurki tkurki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is very easy to add AI generated content, but I fear nobody will keep it up to date nor remove stale content, so let's try to be a bit leaner.

Copy link
Member

@tkurki tkurki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next round...

*/

// Export all public types and functions
export * from './plugin'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to make the API granular, in the direction we are moving in with Server API, or are we happy like this? (don't have a strong opinion on this, you have much better insight here)

@tkurki
Copy link
Member

tkurki commented Dec 19, 2025

There's a build failure that needs addressing: https://github.com/SignalK/signalk-server/actions/runs/20374772192

@dirkwa
Copy link
Contributor Author

dirkwa commented Dec 19, 2025

There's a build failure that needs addressing: https://github.com/SignalK/signalk-server/actions/runs/20374772192

It was introduced by your last commit:

7f8086f

no worries, I will look into it later, want you to finish all first. 04:27am here, so still plenty of "day" left :).

@dirkwa dirkwa changed the title Add support for WASM plugins (with examples) Add support for WASM plugins (with examples), Radar API, Plugin Lifecycle Dec 20, 2025
@tkurki
Copy link
Member

tkurki commented Jan 2, 2026

I really, really wish you had not included the hotplug mechanism in this PR. It adds complexity that is not directly connected to what I think is the core, the wasm plugin mechanism. For example there's a nontrivial amount of code to disable webapps for webapp & plugin combinations.

But what I find really odd is that the hotplug mechanism does not hotplug plugins and webapps that are installed from the App store. I would think that the most important hotplug feature: not needing to restart the server to get access to the newly added addins. Is loading newly installed addins without restart not supported? Only developers toggle things on and off, end users rarely do that.

Would it be possible to create separate PRs for the wasm support (i'm ok with including radar api, even if i would like to have that separate also) and hotplug? I would love to move forward with wasm.

Related: many parts of hotplug.md now read like a PR description, not a long term document. I am personally not very fond of repeating the application code verbatim in documents, as code may evolve and often docs are not updated. To me permanent documents should not describe in detail the steps how something was implemented, but how it works.

@dirkwa
Copy link
Contributor Author

dirkwa commented Jan 2, 2026

Why Hotplug Exists in the WASM PR

The hotplug mechanism was originally added for WASM plugin lifecycle management:

  1. Toggle the WASM runtime interface on/off in server settings
  2. Enable/disable individual WASM plugins without restart
  3. Handle WASM plugin crashes with automatic recovery

Your Observation is Correct - But There's an Opportunity

You're right that the current hotplug doesn't support "install and use immediately" for App Store plugins. However, here's what's interesting: WASM plugins CAN support this - the infrastructure exists:

  • discoverAndRegisterWasmPlugins() can re-scan node_modules/ at runtime
  • WASM modules are loaded dynamically (no Node.js require() cache issues)
  • This is currently triggered only on interface toggle, but could be triggered after App Store install

Node.js plugins cannot easily support this due to module caching and Express route registration at startup.

Proposal

Option A: Make "Install & Use Immediately" a WASM Advantage

  • Wire up App Store install completion to trigger WASM plugin discovery
  • This makes hotplug a core WASM feature, not separate complexity
  • End users get immediate value from WASM plugins
  • Justifies keeping hotplug in the WASM PR

Option B: Split the PR as You Requested

  • Extract hotplug into a separate PR
  • Keep only minimal WASM lifecycle (start/stop/toggle)
  • Lose the "install & use immediately" opportunity

Which direction would you prefer?

Regarding Node.js Plugin Hotplug

The Node.js hotplug (enable/disable without restart) was added for uniformity - same behavior for both plugin types. We can remove it if you prefer WASM-only scope.

Regarding Documentation

Agreed - hotplug.md reads like a PR description. We'll rewrite it as a technical reference focused on "how it works" rather than implementation steps.

Copy link
Member

@tkurki tkurki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've now tested the assemblyscript example webapps but they failed. The faults don't seem serious. I wonder if there should be a test that compiles them (at least the easy ones with npm based build), starts the server and asserts they are present?

I've also looked a bit into the hotplug infrastructure code. To be honest I think the hotplug is not keeping the core lean. It seems like Claude implemented it piecemeal and the result is not as clear as it could be. The logic seems to be spread in many spots over the codebase. I think that needs rework: after all there are just a few operations that actually change what plugins and webapps are available:

  • initial plugins and webapps registering & enablement
  • plugin enable/disable
  • install / uninstall of plugins and webapps

Modifying the app 'splugins and webapps properties is imho a bad idea: I think the code would be easier to understand if we either

  • always filter on the fly to app properties to get enabled ones
  • keep separate data structures for all and enabled ones

The preexisting code is a bit weird, because it started as webapps and plugins being totally separate, but now that line has blurred. I think a single data structure holding both would be better. Room for improvement.

I am not totally against hotplug, but imho it should start from the users' perspective, where the main painpoints afaik are requiring restart for

  • new plugin/webapp installs (solvable)
  • uninstalls (partly solvable)
  • updates (not solvable for plugin routes, webapps ok)

(At this point I read your reply to my separate comment)
I think we should split the PR, not include any hotplug features, and then armed with the knowledge gained here reimplement the parts of hotplug that are feasible, from scratch with a bit better code organisation.

Copy link
Member

@tkurki tkurki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new package assemblyscript-plugin-sdk needs to be included in container build from master and in release workflows.

In master container build packages are built and stored as build artifacts so that the container build step can use them, as they have not yet been published in npm.

https://github.com/SignalK/signalk-server/blob/master/.github/workflows/build-docker.yml#L23-L39

Release workflow checks the packages' versions against npm and publishes new versions as needed.

https://github.com/SignalK/signalk-server/blob/master/.github/workflows/release.yml

Copy link
Member

@tkurki tkurki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making progress, I see "Hello from AssemblyScript!" in my DataBrowser!

Some more details to tweak.

@dirkwa dirkwa requested a review from tkurki January 6, 2026 02:14
- Add AssemblyScript plugin SDK for WASM plugin development
- Support WASM plugins written in Rust, Go, .NET, and AssemblyScript
- Implement Component Model bindings for SignalK API
- Add plugin lifecycle management (load, start, stop, unload)
- Support multiple WASM formats (Component Model, standard WASM)
- Add TCP socket API for network-capable WASM plugins
- Implement plugin configuration storage via plugin-config-data
- Support WASM plugin HTTP endpoints and webapps
- Add comprehensive documentation and example plugins
- Fix Asyncify race conditions for network-capable WASM plugins
- Make WASM runtime toggleable via server settings
@tkurki
Copy link
Member

tkurki commented Jan 8, 2026

I think we are in a good enough shape with this. The commit log is not worth keeping and I don't want 100+ tweakthisandthat commits in master, so I'd like to split this to two commits. I don't really care if the split is 100% accurate or that they are 100% independent, but would be still good practise imho.

This is how Claude would split it: https://github.com/tkurki/signalk-server/pull/new/WASM_WASIX-split

How would you like to proceed? This is your work, so don't want my name on it.

@dirkwa
Copy link
Contributor Author

dirkwa commented Jan 9, 2026

This is how Claude would split it: https://github.com/tkurki/signalk-server/pull/new/WASM_WASIX-split

How would you like to proceed? This is your work, so don't want my name on it.

No worries @tkurki, I think in reality you spent at least as much time on it as I did.
Feel free to publish it your way. Happy to see that we are going a massive step forward here.

@dirkwa
Copy link
Contributor Author

dirkwa commented Jan 9, 2026

Good news!

C# for WASM might work soon.

bytecodealliance/wit-bindgen#1489 (comment)

@tkurki tkurki changed the title Add support for WASM plugins (with examples), Radar API, Plugin Lifecycle Add support for WASM plugins (with examples) Jan 9, 2026
@tkurki tkurki merged commit 0494486 into SignalK:master Jan 9, 2026
5 checks passed
@tkurki
Copy link
Member

tkurki commented Jan 9, 2026

@tkurki
Copy link
Member

tkurki commented Jan 9, 2026

Fixed in fd61431

@msallin
Copy link

msallin commented Jan 9, 2026

🚀 🚀 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants