[Web Runtime] rclnodejs/web SDK guide + JavaScript and TypeScript browser demos#1514
Open
minggangw wants to merge 15 commits into
Open
[Web Runtime] rclnodejs/web SDK guide + JavaScript and TypeScript browser demos#1514minggangw wants to merge 15 commits into
rclnodejs/web SDK guide + JavaScript and TypeScript browser demos#1514minggangw wants to merge 15 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds user-facing documentation and runnable browser demos for the rclnodejs/web Web Runtime, positioning “Browser ↔ ROS 2” as a first-class feature and providing a guided path for front-end developers to use the typed browser SDK + capability allow-list runtime.
Changes:
- Added a comprehensive
rclnodejs/webbrowser SDK tutorial covering connection forms, typed verbs, BigInt wire encoding, error codes, and curl usage. - Introduced two browser demos: a no-toolchain static HTML demo and a Vite+TypeScript demo (both with matching runtime servers/config).
- Restructured the top-level README to highlight browser-to-ROS 2 support and link to the new tutorial/demos.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tutorials/web.md | New end-to-end browser SDK guide and reference for connection forms, typing, and error codes. |
| tutorials/README.md | Adds an index entry linking to the new web tutorial. |
| README.md | Promotes “Browser ↔ ROS 2” to a top-level feature section and links to the new guide. |
| demo/web/README.md | New entrypoint README describing available web demos and the CLI-driven workflow. |
| demo/web/javascript/web.json | Sample allow-list config for rclnodejs-web matching the JS demo panels. |
| demo/web/javascript/server.js | Demo runtime server (WS+HTTP) plus a small static file server for the no-toolchain page. |
| demo/web/javascript/index.html | No-toolchain browser demo UI and client logic. |
| demo/web/javascript/README.md | Instructions and explanation for the no-toolchain demo. |
| demo/web/javascript/package.json | Minimal scripts for running the JS demo server. |
| demo/web/typescript/vite.config.ts | Vite config targeting ES2022 for top-level await compatibility. |
| demo/web/typescript/tsconfig.json | Strict TS config for the Vite demo. |
| demo/web/typescript/src/style.css | Styling for the TS demo page. |
| demo/web/typescript/src/main.ts | Typed browser demo client (call/publish/subscribe + transport toggle). |
| demo/web/typescript/server.ts | Typed runtime server showing end-to-end TS usage of the server runtime API. |
| demo/web/typescript/README.md | Instructions for running the TS demo (runtime + Vite). |
| demo/web/typescript/package.json | Demo dependencies and scripts (Vite/tsx/typecheck). |
| demo/web/typescript/index.html | TS demo page and embedded examples. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| relPath = urlPath.replace(/^\/+/, ''); | ||
| } | ||
| const filePath = path.resolve(baseDir, relPath); | ||
| if (!filePath.startsWith(baseDir)) { |
Comment on lines
+81
to
+99
| async function reconnect(mode: Mode): Promise<void> { | ||
| await teardown(); | ||
| setEndpoint(mode); | ||
| setStatus(`connecting (${mode})…`); | ||
| try { | ||
| ros = await connect(ENDPOINTS[mode]); | ||
| setStatus(`connected (${mode})`, 'ok'); | ||
| } catch (e) { | ||
| setStatus(`failed: ${String(e)}`, 'err'); | ||
| return; | ||
| } | ||
|
|
||
| // Always-on chatter subscription; over HTTP this lazily opens | ||
| // the WS sibling endpoint (subscribe always uses WS). | ||
| try { | ||
| await ros.subscribe<'std_msgs/msg/String'>('/web_demo_chatter', (msg) => | ||
| log('chatLog', `<- ${msg.data}`) | ||
| ); | ||
| } catch (e) { |
Comment on lines
+268
to
+287
| async function reconnect(mode) { | ||
| await teardown(); | ||
| setEndpoint(mode); | ||
| setStatus(`connecting (${mode})…`); | ||
| try { | ||
| ros = await connect(ENDPOINTS[mode]); | ||
| setStatus(`connected (${mode})`, 'ok'); | ||
| } catch (e) { | ||
| setStatus(`failed: ${e.message || e}`, 'err'); | ||
| return; | ||
| } | ||
| // Bind the always-on /web_demo_chatter subscription on every | ||
| // reconnect. Over HTTP this lazily opens the WS sibling. | ||
| try { | ||
| await ros.subscribe('/web_demo_chatter', (msg) => | ||
| log('chatLog', `<- ${msg.data}`), | ||
| ); | ||
| } catch (e) { | ||
| log('chatLog', `subscribe failed: ${e.message} (${e.code})`, 'err'); | ||
| } |
| createRuntime, | ||
| WebSocketTransport, | ||
| HttpTransport, | ||
| } = require('../../../lib/runtime'); |
| "typecheck": "tsc --noEmit" | ||
| }, | ||
| "dependencies": { | ||
| "rclnodejs": "github:minggangw/rclnodejs-1#feat/web-tutorial-and-demos" |
| capability runtime. One string generic per call gives request, | ||
| response, and message types; a `web.json` allow-list is the public | ||
| API surface; the same capabilities are also reachable over plain | ||
| HTTP for `curl`, Postman, and AI-agent tool-use. _New in `2.0.0`._ |
Comment on lines
+174
to
+175
| > for these fields is `\`${number}n\``. JavaScript's `BigInt`literal | ||
| syntax happens to round-trip cleanly through`String(42n)`. |
User-facing learning material for the typed Web SDK + capability
runtime introduced in the previous commits.
Tutorial:
- tutorials/web.md: front-end-developer guide. Covers connect() URL
forms (WebSocket vs. HTTP vs. split endpoints), the typed verb API
(call / publish / subscribe) with single-string-generic typing
derived from generated MessagesMap / ServicesMap, the '42n' BigInt
wire convention, structured error codes, and curl recipes.
- tutorials/README.md: index entry pointing at it.
JavaScript demo (no toolchain):
- demo/web/javascript/{server.js, index.html, web.json, package.json,
README.md}. Single static HTML page that talks to a real ROS 2
graph using only <script type='module'> + the SDK's ESM file.
Mounts both transports; page has a transport toggle and a curl
panel demonstrating the same call/publish/reject scenarios.
TypeScript + Vite demo:
- demo/web/typescript/{server.ts, src/main.ts, src/style.css,
index.html, package.json, tsconfig.json, vite.config.ts, README.md}.
Same four panels as the JS demo, but written in TypeScript so the
IDE autocomplete derived from the generated types is visible end to
end.
demo/web/README.md: parent README cross-linking the two demos and
showing the JSON allow-list (`web.json`) shape.
- README 'Browser ↔ ROS 2' bullet leads with the three-word value
prop (typed, allow-listed, curl-able) and substantiates each one
inline.
- tutorials/web.md §8 'How it compares' restructured around the
decision: rclnodejs/web is the default for new code; rosbridge
remains correct for graph introspection / Actions / fleet UIs.
New keystone callout 'Why we don't try to hide the ROS graph'
pre-empts the 'isn't this just modernised roslibjs?' pushback.
Sibling-vs-competitor framing for rosocket made explicit.
- Strip forward-looking promises ('on the roadmap',
'coming in a follow-up') from §5 reconnect note, §8 actions row,
and §9 auth/actions bullets — replaced with present-tense facts.
A reasonable reflex on first reading is 'shouldn't both bridges use the same URL shape?' Add a blockquote in §8 'Sibling, not competitor' that names the URL difference as deliberate and explains the multiplexing model behind it: rosocket exposes one socket per resource (path is the resource); rclnodejs/web exposes one socket per session (resource lives in the frame, supports call/publish/ subscribe multiplex). Same wire, different contract.
Mirror the rosocket/ layout: rosocket/README.md is the package-shaped reference for the rosocket subpackage, so rclnodejs/web's user-facing guide should live at web/README.md too. Same content, just renamed (git tracks it as a rename, history preserved). - tutorials/web.md → web/README.md (292 lines, no content change beyond intro link) - README.md cross-refs updated (Get-started row + 'Browser ↔ ROS 2' bullet) - tutorials/README.md entry now points at ../web/README.md - web/README.md intro path adjusted from 'web/client.js' to './client.js' since the doc is now next to the source - See-also section in web/README.md drops 'web/client.js' → './client.js' This also gives npmjs.com/package/rclnodejs/web a real rendered landing page (npm renders subpath READMEs), matching what's been true for rosocket since 2.0.0-beta.0.
83e45f1 to
5d22ab0
Compare
rclnodejs/web SDK guide + JavaScript and TypeScript browser demos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A typed Web SDK guide for
rclnodejs/web, two end-to-end browser demos (zero-build JavaScript + Vite TypeScript), and the surrounding doc / terminology / packaging cleanup.What's new
web/README.md(new) — single source of truth for the browser SDK: server runtime, three-verb client (call/publish/subscribe),connect()URL shapes, lifecycle,curl-able HTTP transport, and arclnodejs/webvs.rosbridge+roslibjstable.demo/web/javascript/(new) — zero-build demo:node runtime.js+node static.js, nonpm install, no bundler.demo/web/typescript/(new) — Vite + tsx demo with the typed three-verb client;npm run serverwraps tsx withNODE_OPTIONS=--no-deprecationto silence Node'sDEP0205noise.bin/rclnodejs-web.js— CLI tightened: repeatable--call/--publish/--subscribeflags,web.jsonmode, friendlier startup banner.README.md,scripts/npmjs-readme.md,tutorials/README.md— repositioned around three browser stories (rclnodejs/web,rosocket, none-of-the-above) and link the new SDK guide.rosocket/README.md+demo/rosocket/README.md— recast as the lighter sibling; cross-link to the SDK guide for the rosbridge comparison.lib/runtime/dispatcher.js,lib/runtime/transports/ws.js,lib/message_serialization.js,rosocket/index.js,test/test-rosocket.js) — comment / wording only, no behaviour change.Fix: #1510