Repository navigation
WASM + typescript-go - #1677
WASM + typescript-go#1677SamuelMarks wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Don't TSGO benefits evaporate with WASM? https://github.com/auvred/hybrid-type-aware-linting-performance#why-wasm-is-not-considered
The only audience that would require a tsgo-WASM backed ts-morph implementation that comes to mind is a couple of specific lambda runtimes and browsers that don't support anything else. I estimate there is a very small number of use cases that could leverage the WASM version. And even something like jsdocs.io needs it exclusively because of the way it's deployed right now - to Vercel functions.
And as I see it, the primary use case of ts-morph is purpose-built linters, formatters, codemods, CLIs, etc, most of which run in environments with access to faster tsgo communication options.
If wasm were to be supported, it shouldn't dictate the exposed API surface of ts-morph, and better be hidden behind a unified interface shared with ffi/ipc backed implementations
| @@ -0,0 +1,29 @@ | |||
| # Pull Request Strategy | |||
|
|
|||
| As outlined in the Comprehensive Migration Plan (`PLAN.md`), replacing the JavaScript TypeScript compiler with `typescript-go` (Wasm) involves working across two repositories. Here is the formal strategy for upstream integration. | |||
| - **Native Rust Bindings (N-API):** Rejected due to the operational overhead of distributing native binaries across platforms compared to a single universally runnable `.wasm` file. | ||
|
|
||
| ## Implementation Details | ||
| Refer to `PLAN.md` for the multi-phase implementation pipeline, notably the `HandleRegistry` and `FinalizationRegistry` mechanisms used to bridge the GC gap between Go and V8. No newline at end of file |
|
@nikelborm Thanks for jumping in and for the great feedback! You raise some very valid points regarding WASM performance versus native targets. I completely agree that for the primary use cases of However, I want to give some specific context on why I'm pushing for this and why the audience for a WASM-backed I am the author of cdd-ts and cdd-web-ui, part of a suite for "Compiler Driven Development" (CDD). CDD provides bidirectional synchronization between API specifications (like OpenAPI) and code implementations (SDKs, Servers, CLIs). Unlike traditional string-templating code generators that overwrite files, This is where WASM becomes mission-critical.
By switching my tooling to a So while I wholeheartedly agree that As mentioned in the PR description, this was mostly to get the conversation started. My next steps will focus on abstracting the bridge to allow for native FFI/IPC on the desktop/server side while preserving the WASM fallback for browser clients. I'd love to hear your thoughts on preferred IPC/FFI approaches for Go <-> Node.js bridging! PS: Live hosted WASM demo in case you're interested https://offscale.io/cdd-web-ui - everything open-source of course |
|
This part:
Doesn't necessarily dictate this part:
Web browsers are not limited to only interacting with file systems, be it interacting with the host's native OS file system, or interacting with origin-scoped OPFS. There are approaches like the one taken by https://npmx.dev/, which lets the user interact with a running local daemon of npmx, and NPMX's cloud never can reach any credential file stored on the device, as well as process it, while still making the user able to do all the nice interactions with private APIs and files, that are coming from the user's own machine, and not proxied through npmx's cloud, through the web interface, that's not shipped as part of any binary to the client, and is loaded as a plain https page from the cloud.
This part is not an achievement of WASM; any TSGO communication option in a sufficiently local context will let the dev "instantly parse, diff, and synthesize the updated SDK code in the adjacent pane in real time". And the instant part is actually achieved not by selecting any specific communication options, but by making the compiler stateful -- by enabling incremental typechecking and correctly managing the hierarchy of dependencies in a project and cross-package importing. Lastly. Could you explain why you need the tsgo compiler packaged into WASM? Did you put all the C89, C++, C#, Ruby, Swift, etc compilers listed on cdd-web-ui into WASM as well? This is an insane amount of work, and I don't understand why you would do it when things like StackBlitz, peerd, Oh My Git, Effect.ts playground and countless others use the same approach implemented by things like webcontainers.io, CheerpX, v86, webvm which would essentially need you to do nothing on your side like maintaining unofficial tsgo-wasm connector, and make it possible to use the official tsgo:ffi/tsgo:ipc integration in this virtualized environment. If avoiding installing any new tooling on the user's machine is one of the core values for your project, then virtualized environments are a universally accepted answer |
|
@nikelborm "Did you put all the C89, C++, C#, Ruby, Swift, etc compilers listed on cdd-web-ui into WASM as well? This is an insane amount of work" Thank you! - It took f-o-r-e-v-e-r to engineer and get working in the browser. - Each compiler is written in the language it targets and is completely standalone. - Then my cdd-web-ui brings together all 13 language compilers into one fully client-side bidirectional (OpenAPI ⇄ language) browser-based code editor. They are all whitespace and comment sensitive, and for the TypeScript target ts-morph is used extensively. Without exception: every single component is open-source under (Apache-2.0 OR MIT) or even more permissive licenses. (and purely client-side; as in you can host just the static files on any CDN, |

This doesn't need to be merged, more it's just to start a new conversation à la #1656
FWIW: I got my cdd-ts.wasm—Compiler Driven Development (CDD) being a suite of open-source compilers, each written in the language they target, for going to/fro OpenAPI [and more!]—down from 138MB to 106MB. Just by switching from typescript to typescript-go.
Description
This PR fundamentally shifts the compiler architecture of
ts-morphby replacing the JavaScripttypescriptpackage with Microsoft'stypescript-goport compiled to WebAssembly (Wasm).As detailed in
rfcs/RFC-0002-Go-Wasm-Compiler-Migration.md, this brings massive performance improvements (up to 60% faster cold parsing) and slashes the V8 memory overhead by keeping AST structures inside the Wasm linear memory.Key Changes
go buildandwasm-opt(Binaryen) inscripts/build-wasm.ts.FinalizationRegistryto synchronize Go's garbage collector with V8.Project.create()to accommodate asynchronous Wasm compilation.WasmNode,WasmType, andWasmSymbolproxies that lazily query the Wasm runtime usingsyscall/js.npm run test:wasm) and added E2E real-world benchmarks.Notes for Reviewers
packages/compiler-go-source).npm installanddeno task setupto build the new Wasm dependencies locally.