Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
**Key features:** Topics, Services, Actions, Parameters, Lifecycle Nodes, TypeScript support, RxJS Observables, Electron integration, ROS 2 in the browser (typed Web SDK + thin WebSocket gateway — `rclnodejs/web`, `rosocket`), and prebuilt binaries for Linux x64/arm64.

```javascript
const rclnodejs = require('rclnodejs');
rclnodejs.init().then(() => {
const node = new rclnodejs.Node('publisher_example_node');
const publisher = node.createPublisher('std_msgs/msg/String', 'topic');
publisher.publish(`Hello ROS 2 from rclnodejs`);
node.spin();
});
import rclnodejs from 'rclnodejs';

await rclnodejs.init();
const node = new rclnodejs.Node('publisher_example_node');
const publisher = node.createPublisher('std_msgs/msg/String', 'topic');
publisher.publish(`Hello ROS 2 from rclnodejs`);
node.spin();
```

This example assumes your ROS 2 environment is already sourced.
Expand Down Expand Up @@ -105,7 +105,7 @@ npm install
2. Run a publisher example from this checkout.

```bash
node example/topics/publisher/publisher-example.cjs
node example/topics/publisher/publisher-example.mjs
```

More runnable examples in [example/](https://github.com/RobotWebTools/rclnodejs/tree/develop/example) and step-by-step guides in [tutorials/](./tutorials/).
Expand Down Expand Up @@ -146,7 +146,7 @@ how much glue you want to write.
rclnodejs supports [RxJS](https://rxjs.dev/) Observable subscriptions for reactive programming with ROS 2 messages. Use operators like `throttleTime()`, `debounceTime()`, `map()`, and `combineLatest()` to build declarative message processing pipelines.

```javascript
const { throttleTime, map } = require('rxjs');
import { throttleTime, map } from 'rxjs';

const obsSub = node.createObservableSubscription(
'sensor_msgs/msg/LaserScan',
Expand All @@ -173,7 +173,7 @@ rclnodejs auto-generates JavaScript bindings and TypeScript declarations for eve
Use the generated types directly:

```javascript
const rclnodejs = require('rclnodejs');
import rclnodejs from 'rclnodejs';
let stringMsgObject = rclnodejs.createMessageObject('std_msgs/msg/String');
stringMsgObject.data = 'hello world';
```
Expand All @@ -199,9 +199,9 @@ TypeScript declaration files are included in the package and exposed through the
```jsonc
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"target": "es2020",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"target": "es2022",
},
}
```
Expand Down
6 changes: 2 additions & 4 deletions benchmark/rclnodejs/service/client-stress-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

/* eslint-disable camelcase */
const { program } = require('commander');
const rclnodejs = require('../../../index.js');
import { program } from 'commander';
import rclnodejs from '../../../index.js';

program
.option('-r, --run <n>', 'How many times to run', '1')
Expand Down
6 changes: 2 additions & 4 deletions benchmark/rclnodejs/service/service-stress-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

/* eslint-disable camelcase */
const { program } = require('commander');
const rclnodejs = require('../../../index.js');
import { program } from 'commander';
import rclnodejs from '../../../index.js';

program
.option('-s, --size <size_kb>', 'The block size in KB', '1')
Expand Down
6 changes: 2 additions & 4 deletions benchmark/rclnodejs/topic/publisher-stress-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

/* eslint-disable camelcase */
const { program } = require('commander');
const rclnodejs = require('../../../index.js');
import { program } from 'commander';
import rclnodejs from '../../../index.js';

program
.option('-s, --size <size_kb>', 'The block size', '1')
Expand Down
4 changes: 1 addition & 3 deletions benchmark/rclnodejs/topic/subscription-stress-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

const rclnodejs = require('../../../index.js');
import rclnodejs from '../../../index.js';

async function main() {
try {
Expand Down
8 changes: 4 additions & 4 deletions demo/rosocket/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ library required.
- Subscribe to and publish on `/chatter` (`std_msgs/msg/String`).
- Call `/add_two_ints` (`example_interfaces/srv/AddTwoInts`) — the
service implementation lives in
[`example/services/service/service-example.cjs`](../../example/services/service/service-example.cjs)
[`example/services/service/service-example.mjs`](../../example/services/service/service-example.mjs)
and is launched in a second terminal.

## Layout

- `server.cjs` — `rclnodejs` node + `startRosocket` bridge only.
- `server.mjs` — `rclnodejs` node + `startRosocket` bridge only.
- `index.html` — single-file browser client using only built-in
`WebSocket` and `JSON`.

Expand All @@ -27,12 +27,12 @@ library required.
source /opt/ros/$ROS_DISTRO/setup.bash

# 2. Terminal A — start the WebSocket gateway
node demo/rosocket/server.cjs
node demo/rosocket/server.mjs
# [rosocket-demo] listening on ws://localhost:9000 (bind=0.0.0.0)

# 3. Terminal B — start the AddTwoInts service so the browser has
# something to call
node example/services/service/service-example.cjs
node example/services/service/service-example.mjs
```

The server binds to `0.0.0.0:9000` so it is reachable from any host
Expand Down
78 changes: 0 additions & 78 deletions demo/rosocket/server.cjs

This file was deleted.

69 changes: 69 additions & 0 deletions demo/rosocket/server.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (c) 2026 RobotWebTools Contributors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0

// rosocket demo server.
//
// Bridges two ROS 2 endpoints to plain WebSocket URLs so a browser can
// drive them with built-in `WebSocket` + `JSON`, no client library:
//
// ws://<host>:9000/topic/chatter std_msgs/msg/String
// ws://<host>:9000/service/add_two_ints example_interfaces/srv/AddTwoInts
//
// Run inside WSL (where ROS 2 is sourced):
// node demo/rosocket/server.mjs
//
// To exercise the service, start the existing AddTwoInts example in a
// second terminal (it implements `/add_two_ints`):
// node example/services/service/service-example.mjs
//
// Then open demo/rosocket/index.html on the Windows host browser. WSL2
// forwards localhost so `ws://localhost:9000` works as-is. See README.md
// for fallback instructions.

import rclnodejs from '../../index.js';
import { startRosocket } from '../../rosocket/index.js';

const PORT = Number(process.env.PORT) || 9000;
const HOST = process.env.HOST || '0.0.0.0';

await rclnodejs.init();
const node = rclnodejs.createNode('rosocket_demo_node');
rclnodejs.spin(node);

const bridge = await startRosocket({
node,
port: PORT,
host: HOST,
topicTypes: {
'/chatter': 'std_msgs/msg/String',
},
serviceTypes: {
'/add_two_ints': 'example_interfaces/srv/AddTwoInts',
},
});

const displayHost = HOST === '0.0.0.0' || HOST === '::' ? 'localhost' : HOST;
const baseUrl = `ws://${displayHost}:${bridge.port}`;
console.log(
`[rosocket-demo] listening on ${baseUrl} (bind=${HOST}:${bridge.port})`
);
console.log('[rosocket-demo] endpoints:');
console.log(` ${baseUrl}/topic/chatter`);
console.log(` ${baseUrl}/service/add_two_ints`);
console.log('Open demo/rosocket/index.html in the host browser to try it.');

const shutdown = () => {
bridge.close().finally(() => {
try {
rclnodejs.shutdown();
} catch (_) {}
process.exit(0);
});
};
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
2 changes: 1 addition & 1 deletion demo/typescript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Asynchronous actions with progress feedback and cancellation

### Modern Development

- **ES2020+ syntax** with async/await patterns
- **ES2022+ syntax** with async/await patterns
- **Modular architecture** with clean separation of concerns
- **Error boundaries** with comprehensive exception handling
- **Graceful shutdown** handling for SIGINT/SIGTERM
Expand Down
2 changes: 0 additions & 2 deletions demo/typescript/actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ demo/typescript/actions/
├── src/
│ ├── client.ts # Action client implementation
│ └── server.ts # Action server implementation
├── types/
│ └── rclnodejs.d.ts # Type definitions
├── package.json # Project configuration
├── tsconfig.json # TypeScript configuration
├── .gitignore # Git ignore rules
Expand Down
9 changes: 5 additions & 4 deletions demo/typescript/actions/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"lib": ["ES2020", "DOM"],
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2022", "DOM"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
Expand All @@ -16,7 +17,7 @@
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"types": ["node"],
"typeRoots": ["./types", "./node_modules/@types"]
"typeRoots": ["./node_modules/@types"]
},
"include": [
"src/**/*"
Expand Down
4 changes: 2 additions & 2 deletions demo/typescript/services/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ Starting TypeScript Service Client Demo...

This demo includes:

- **Local Type Definitions**: Custom TypeScript definitions for rclnodejs in `types/rclnodejs.d.ts`
- **Package Type Definitions**: Uses the in-tree rclnodejs TypeScript declarations (no local stub types)
- **Service Types**: Type definitions for `example_interfaces/srv/AddTwoInts`
- **Strict Type Checking**: Full TypeScript strict mode enabled
- **Build Pipeline**: Automated compilation with shebang fixing for executable JavaScript
Expand Down Expand Up @@ -292,7 +292,7 @@ Modify the service callback to implement your own business logic:
```
Type errors in service definitions
```
**Solution**: Check the type definitions in `types/rclnodejs.d.ts` match your usage.
**Solution**: Ensure the in-tree rclnodejs package is built so its TypeScript declarations are available.

### Debugging Tips

Expand Down
9 changes: 5 additions & 4 deletions demo/typescript/services/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"lib": ["ES2020"],
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
Expand All @@ -16,7 +17,7 @@
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"types": ["node"],
"typeRoots": ["./types", "./node_modules/@types"]
"typeRoots": ["./node_modules/@types"]
},
"include": [
"src/**/*",
Expand Down
Loading
Loading