Add browser JS support using WASM build#5
Conversation
7345313 to
424e1e2
Compare
|
don't merge/review just yet @riyaneel, I'm going to reduce the duplication of the node/browser versions by making them both extend a base class, instead of re-implementing the whole surface twice. |
a18fa0e to
9b3a9e2
Compare
|
If you merge this I recommend renaming |
1c4352e to
e8d3138
Compare
|
ok ready for review |
|
Hi, Thanks for taking the time to put this PR together. I have reviewed the code, and the quality of the JS/TS integration is impressive. The That being said, after looking closely at the SPSC ring buffer implementation, there is a fundamental architectural blocker. I cannot accept re-implementing the core in Rust. To integrate browser WASM support, the existing C++ core must be compiled using Emscripten. Here is the reasoning behind this decision:
The safest way to bring WASM support to the browser is to use the C++ core as the single source of truth. I can easily isolate POSIX-specific system calls by using On the JavaScript side, your architecture is solid, but there are three specific bugs in the unified wrapper that need to be addressed:
I genuinely want to keep your JS/TS wrapper, tests, and examples. If you are open to collaborating on the Emscripten pivot, I want to push the necessary C++ patches directly to this branch so you can connect the Emscripten module to your JS interface. Let me know what you think and how you would like to proceed. |
|
all good! happy to pivot to emscripten, give me a few days to refactor / feel free to push directly to this PR in the meantime. will fix those bugs as well if you don't get to them first. I know the browser side well but I don't know nearly as much about low level C++ / Rust / memory layout optimization, so I'm not surprised there were a few bugs in my v1. It's a good learning experience, thanks to being open to contributions! I do think it may be worth still considering a wasm32 target for now, and leave wasm64 for the future because it's not really stable/commonly used yet. |
|
Appreciate your openness to this pivot. Adapting to the Emscripten pipeline is the right move for the project's long-term stability, and it will guarantee that your JS wrapper operates on top of a fully sanitized core. You make a valid point regarding the However, because I will take care of the C++ and build pipeline. I will implement the |
19cd752 to
1ed98db
Compare
1ed98db to
cb468f1
Compare
|
Hi @pirate, I've just pushed the commits to stabilize the core and the Emscripten toolchain. Everything is set up. As we discussed, I've implemented the 2GB capacity limit in both the shared memory allocation and the C API to protect against 32-bit index overflows on the wasm32 heap. For the zero-copy integration, I added Also renamed Let me know if you hit a wall. |
There was a problem hiding this comment.
now that the browser core uses C++, should we switch this to C++ or leave the example using rust for the demo?
might be cool to keep rust to show that WASM really is language agnostic?
There was a problem hiding this comment.
Yes, but to make it work while keeping the core as the single source of truth, we just need to compile this Rust example using the wasm32-unknown-emscripten target instead of wasm32-unknown-unknown.
Cargo will use emcc as the linker and the rust bindings will link directly against the Emscripten compiled core, generating a single WASM module. Both JS and Rust using the exact same fuzzed/sanitized C API.
|
Awesome, nice work! LGTM, excited to use it |
|
Let me know when you wire up the TS wrapper to the new Emscripten module and patch the three JS bugs we discussed. For the demo, just tell me if you want to try setting up the Emscripten linker for Rust. Ping me when you feel that's ready for the final review. |
Fixes #4
Summary
@tachyon-ipc/corepackage through the packagebrowserfield, leaving Nodemainandtypesresolution unchanged.examples/browser_wasm/rust; the bindings package only exposes reusable transport/API pieces./usr/bin/chromium, and a Rust wasm32 target check.Notes
The browser transport cannot use POSIX shared memory or UNIX sockets, so
socketPathis a page-local endpoint key. The message ring keeps Tachyon's 64-byte header,type_id, alignment, and skip-marker semantics. Browser receives are non-blocking; direct doorbell calls are used instead of polling or browser task scheduling.The browser test runner does not depend on Playwright. It uses raw Chrome DevTools Protocol from a Node 24 driver with the built-in WebSocket client and discovers browsers locally from
CHROMIUM_BIN,/usr/bin/chromium, Linux Chromium aliases, macOS Chrome/Canary/Chromium apps, and cachedms-playwrightChromium installs.Validation
cargo check --manifest-path bindings/rust/Cargo.toml -p tachyon-ipcRUSTC=$(rustup which rustc) cargo check --manifest-path bindings/rust/Cargo.toml -p tachyon-ipc --target wasm32-unknown-unknownRUSTC=$(rustup which rustc) cargo check --manifest-path examples/browser_wasm/rust/Cargo.toml --target wasm32-unknown-unknownnpm run lintinbindings/nodenpm run format:checkinbindings/nodenpm run build:ts && npm run copy:wasminbindings/nodeCHROMIUM_BIN='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' npm run test:browserinbindings/nodebash ci/vendor.sh node && npm run build:nativefollowed bynpm testinbindings/nodenpm run buildinexamples/browser_wasm