Skip to content

feat(wasm): add combined sysml-wasm command - #870

Merged
HuiJun merged 2 commits into
developfrom
feature/sysml-wasm
Oct 4, 2026
Merged

HuiJun merged 2 commits into
developfrom
feature/sysml-wasm

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

What and why

Adds sysml-wasm, a single WebAssembly-friendly command that serves the union of sysml-core (parsing, diagnostics, symbol facts) and sysml-engine (evaluation, instantiation, execution) behind one call(method, paramsJSON). This is the first step toward letting the Node/browser client run against WASM instead of a native sysml-grpc.

Building both into one module avoids duplicating the parser, semantics, runtime and embedded standard library: the combined js/wasm build is 7.79 MB gzipped (5.48 MB Brotli), compared with 12.7 MB gzipped for sysml-engine + sysml-core shipped as separate modules.

  • New internal/frontend/combined.Server:
    • ParseSources / ParseFile parse through the core, then through the engine, and fail with Internal if the two model hashes differ. The core response (roots + diagnostics) is returned, so a hash from either parse works with every later method.
    • GetDiagnostics / GetSymbol go to the core; Evaluate, Instantiate, ExecuteAction and ExecuteState go to the engine.
    • GetServerInfo returns the build version and a fixed list of capabilities for the surface it serves, so the client's existing capability checks refuse unsupported calls cleanly.
    • Every other method answers Unimplemented and points to sysml-grpc.
  • engine.NewWithLibrary / core.NewWithLibrary let both frontends share one frozen standard-library snapshot and take a model bound (0 = unbounded, with explicit Evict). engine.New now loads the library at construction instead of on the first parse.
  • The combined server owns a single 16-model LRU. Every successful hash-routed call refreshes it, and an eviction removes the model from both frontends, so a hash is valid for every method or for none.
  • cmd/sysml-wasm: the js build installs globalThis.sysmlWasm = { version, call }; -stdio, native and wasip1 builds serve the Content-Length-framed JSON-RPC pipe.
  • Makefile: sysml-wasm joins WASM_COMMANDS, and there is a new opt-in native build-sysml-wasm target. It isn't released yet; publishing comes in a follow-up PR.

The existing sysml-engine, sysml-core and sysml-syntax commands are unchanged. The docs site still loads sysml-engine.

How it was verified

  • tests/wasm:
    • sysml-wasm builds for both targets.
    • New combinedSubtests run a stdio session on wasip1 and js, covering ParseFile → Evaluate/GetSymbol/GetDiagnostics/Instantiate on that hash, GetServerInfo, an unserved method, and malformed params followed by a working call.
    • The globalThis.sysmlWasm host surface is exercised from Node.
    • A gzip size budget of 8.3 MB applies.
  • TestCombinedWireParity compares JSON answers with sysmlgrpc.Service, in process, for ParseSources, ParseFile (inline and filePath), GetDiagnostics, GetSymbol, Evaluate, Instantiate, ExecuteAction and ExecuteState. It also checks that a ParseFile hash is accepted by both Evaluate and GetSymbol, and that every advertised capability is one sysml-grpc reports. Retention tests in internal/frontend/combined cover core-only access, engine-only access and re-parsing at the 16-model boundary.
  • TestCombinedDependencies: neither wasm target links protobuf, Connect, gRPC, internal/frontend/grpc, protoconv, stdiorpc or internal/doc/.
  • Unit tests in internal/frontend/combined. Hygiene layering registers the new packages.
  • Run locally: vet for native, js and wasip1; repository-pinned staticcheck and gosec; changelog check; make docs-check and a strict make docs.

Checklist

  • make test and make lint pass locally (targeted packages, lint and the wasm gate run locally; full suite left to CI)
  • Tests added or updated for the change
  • Documentation extended where it already covers the surface (see CONTRIBUTING.md)
  • Changelog entry added as changes/unreleased/<slug>.<section>.md, not as an edit to CHANGELOG.md
  • baselines regenerated and make docs-counts run if a gate count moved (compliance rows need nothing: the census is counted at docs build)
  • No internal work-item labels (waves, slices, F4, K5) in the body, docs, or changelog

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Chrome verification: combined WASM shared-hash flow

I tested f3f0a993f6dd in Chrome 137 with an external localhost page that loads the real js/wasm module and calls globalThis.sysmlWasm.call(...) directly. All 30 checks passed.

  • A single hash from an inline ParseFile worked for every follow-up call: Evaluate, GetSymbol, GetDiagnostics, Instantiate, ExecuteAction and ExecuteState.
  • Values checked:
    • enginedemo::speed = 5 SI::'m/s'
    • 2 ** 70 comes back as bigIntValue "1180591620717411303424"
    • Double(x=6) → y = 12
    • Switch visits off → on
  • A two-document ParseSources hash worked for both evaluation and symbol lookup. The validation fixture reported its one-type diagnostic with the correct source span.
  • GetServerInfo returned the 23 capabilities in the expected order.
  • Errors:
    • Convert returned code 12 (Unimplemented), malformed params returned 3 (InvalidArgument), and an unknown hash returned 5 (NotFound).
    • Each error was followed by a reparse and calls that still worked.
    • No panics or console errors.
Shared hash → action output Validation retained
Shared-hash execution Validation diagnostic

Measured locally without compression: a 31,526,528-byte body, and 262 ms from load to ready. That isn't a network benchmark. I did not run a native sysml-grpc comparison in the browser; TestCombinedWireParity covers parity in Go.

@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review October 3, 2026 23:47
devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@HuiJun
HuiJun merged commit 49d7d13 into develop Oct 4, 2026
24 checks passed
@HuiJun
HuiJun deleted the feature/sysml-wasm branch October 4, 2026 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant